Submitted By: Ken Moffat <ken at linuxfromscratch dot org>
Date: 2009-08-26
Initial Package Version: 1.8.4 (probably also applies to earlier 1.8)
Upstream Status: Applied
Origin: Upstream, via ubuntu.
Description: First part works around the Python vulnerability [ CVE-2009-0318 ],
second part works around gtk+-2.16 changes.  Gnome bugs 569648 and 575267.

--- gnumeric-1.8.4.orig/plugins/python-loader/ChangeLog
+++ gnumeric-1.8.4/plugins/python-loader/ChangeLog
@@ -1,3 +1,9 @@
+2009-01-29  Jon K Hellan  <hellan@acm.org>
+
+	* gnm-py-interpreter.c (gnm_py_interpreter_new): Work around
+	security vulnerability in Python by making argv start with
+	"/dev/null". #569648.
+
 2009-01-18  Jody Goldberg <jody@gnome.org>
 
 	* Release 1.8.4
--- gnumeric-1.8.4.orig/plugins/python-loader/gnm-py-interpreter.c
+++ gnumeric-1.8.4/plugins/python-loader/gnm-py-interpreter.c
@@ -79,7 +79,7 @@
 		G_TYPE_NONE, 0);
 }
 
-static char *plugin_argv[] = {(char *) "gnumeric", NULL};
+static char *plugin_argv[] = {(char *) "/dev/null/python/is/buggy/gnumeric", NULL};
 
 GnmPyInterpreter *
 gnm_py_interpreter_new (GOPlugin *plugin)
--- gnumeric-1.8.4.orig/src/application.h
+++ gnumeric-1.8.4/src/application.h
@@ -79,6 +79,7 @@
 	GnmActionHandler	handler;
 };
 typedef struct {
+	char const *group_name;
 	GSList	   *actions;
 	char	   *layout;
 	char const *domain;
@@ -90,7 +91,8 @@
 			    GnmActionHandler handler);
 void	   gnm_action_free (GnmAction *action);
 
-GnmAppExtraUI *gnm_app_add_extra_ui (GSList *actions, char *layout,
+GnmAppExtraUI *gnm_app_add_extra_ui (char const *group_name,
+				     GSList *actions, char *layout,
 				     char const *domain,
 				     gpointer user_data);
 void	   gnm_app_remove_extra_ui  (GnmAppExtraUI *extra_ui);
--- gnumeric-1.8.4.orig/src/wbc-gtk.c
+++ gnumeric-1.8.4/src/wbc-gtk.c
@@ -3010,7 +3010,7 @@
 	GtkAction       *res;
 
 	details = g_new0 (CustomUIHandle, 1);
-	details->actions = gtk_action_group_new ("DummyName");
+	details->actions = gtk_action_group_new (extra_ui->group_name);
 
 	for (ptr = extra_ui->actions; ptr != NULL ; ptr = ptr->next) {
 		action = ptr->data;
--- gnumeric-1.8.4.orig/src/gnm-pane.c
+++ gnumeric-1.8.4/src/gnm-pane.c
@@ -587,11 +587,15 @@
 		event->keyval == GDK_KP_Decimal ||
 		event->keyval == GDK_KP_Separator;
 
-	if (gtk_im_context_filter_keypress (pane->im_context,event))
+	if (gtk_im_context_filter_keypress (pane->im_context, event))
 		return TRUE;
-	pane->reseting_im = TRUE;
+
+	/* in gtk-2.8 something changed.  gtk_im_context_reset started
+	 * triggering a pre-edit-changed.  We'd end up start and finishing an
+	 * empty edit every time the cursor moved */
+	pane->im_block_edit_start = TRUE;
 	gtk_im_context_reset (pane->im_context);
-	pane->reseting_im = FALSE;
+	pane->im_block_edit_start = FALSE;
 
 	if (gnm_pane_key_mode_sheet (pane, event, allow_rangesel))
 		return TRUE;
@@ -628,7 +632,17 @@
 gnm_pane_focus_in (GtkWidget *widget, GdkEventFocus *event)
 {
 #ifndef GNM_USE_HILDON
+	/* The first call to focus-in was sometimes the first thing to init the
+	 * imcontext.  In which case the im_context_focus_in would fire a
+	 * preedit-changed, and we would start editing. */
+	GnmPane *pane = GNM_PANE (widget);
+	if (pane->im_first_focus)
+		pane->im_block_edit_start = TRUE;
 	gtk_im_context_focus_in (GNM_PANE (widget)->im_context);
+	if (pane->im_first_focus) {
+		pane->im_first_focus = FALSE;
+		pane->im_block_edit_start = FALSE;
+	}
 #endif
 	return (*GTK_WIDGET_CLASS (parent_klass)->focus_in_event) (widget, event);
 }
@@ -645,6 +659,8 @@
 {
 	GtkStyle  *style;
 
+	GNM_PANE (w)->im_block_edit_start = FALSE;
+
 	if (GTK_WIDGET_CLASS (parent_klass)->realize)
 		(*GTK_WIDGET_CLASS (parent_klass)->realize) (w);
 
@@ -667,8 +683,10 @@
 	pane = GNM_PANE (widget);
 	g_return_if_fail (pane != NULL);
 
-	if (pane->im_context)
+	if (pane->im_context) {
+		pane->im_block_edit_start = TRUE;
 		gtk_im_context_set_client_window (pane->im_context, NULL);
+	}
 
 	(*GTK_WIDGET_CLASS (parent_klass)->unrealize)(widget);
 }
@@ -733,10 +751,7 @@
 		pango_attr_list_unref (pane->preedit_attrs);
 	gtk_im_context_get_preedit_string (pane->im_context, &preedit_string, &pane->preedit_attrs, &cursor_pos);
 
-	/* in gtk-2.8 something changed.  gtk_im_context_reset started
-	 * triggering a pre-edit-changed.  We'd end up start and finishing an
-	 * empty edit every time the cursor moved */
-	if (!pane->reseting_im &&
+	if (!pane->im_block_edit_start &&
 	    !wbcg_is_editing (wbcg) && !wbcg_edit_start (wbcg, TRUE, TRUE)) {
 		gtk_im_context_reset (pane->im_context);
 		pane->preedit_length = 0;
@@ -911,8 +926,9 @@
 
 	pane->im_context = gtk_im_multicontext_new ();
 	pane->preedit_length = 0;
-	pane->preedit_attrs = NULL;
-	pane->reseting_im = FALSE;
+	pane->preedit_attrs    = NULL;
+	pane->im_block_edit_start = FALSE;
+	pane->im_first_focus = TRUE;
 
 	GTK_WIDGET_SET_FLAGS (canvas, GTK_CAN_FOCUS);
 	GTK_WIDGET_SET_FLAGS (canvas, GTK_CAN_DEFAULT);
@@ -2062,9 +2078,9 @@
 			"width-pixels", 1,
 			NULL);
 	else {
-		static char const dat [] = { 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88 };
+		static unsigned char const dat [] = { 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88 };
 		GdkBitmap *stipple = gdk_bitmap_create_from_data (
-			GTK_WIDGET (pane)->window, dat, 8, 8);
+			GTK_WIDGET (pane)->window, (const gchar *)dat, 8, 8);
 		foo_canvas_item_set (pane->size_guide.guide, "fill-stipple", stipple, NULL);
 		g_object_unref (stipple);
 	}
--- gnumeric-1.8.4.orig/src/gnm-pane-impl.h
+++ gnumeric-1.8.4/src/gnm-pane-impl.h
@@ -30,14 +30,13 @@
 	gboolean   sliding_adjacent_h, sliding_adjacent_v;
 
 	/*  IM */
-	guint      reseting_im :1;	/* quick hack to keep gtk_im_context_reset from starting an edit */
+	guint im_block_edit_start :1; /* see gnm_pane_key_press for details */
+	guint im_first_focus	  :1; /* see gnm_pane_init for details */
 	guint      preedit_length;
 	GtkIMContext  *im_context;
 	PangoAttrList *preedit_attrs;
-	gboolean insert_decimal;
-
-
 
+	gboolean insert_decimal;
 
 	int		 index;
 	struct {
--- gnumeric-1.8.4.orig/src/gnm-plugin.c
+++ gnumeric-1.8.4/src/gnm-plugin.c
@@ -363,7 +363,7 @@
 	PluginServiceUI *service_ui = GNM_PLUGIN_SERVICE_UI (service);
 	GError *err = NULL;
 	char *full_file_name;
-	char *xml_ui;
+	char *xml_ui, *group_name;
 	char const *textdomain;
 
 	GO_INIT_RET_ERROR_INFO (ret_error);
@@ -380,9 +380,11 @@
 	g_free (full_file_name);
 
 	textdomain = go_plugin_get_textdomain (service->plugin);
-	service_ui->layout_id = gnm_app_add_extra_ui (
+	group_name = g_strconcat (go_plugin_get_id (service->plugin), service->id, NULL);
+	service_ui->layout_id = gnm_app_add_extra_ui (group_name,
 		service_ui->actions,
 		xml_ui, textdomain, service);
+	g_free (group_name);
 	service->is_active = TRUE;
 }
 
--- gnumeric-1.8.4.orig/src/application.c
+++ gnumeric-1.8.4/src/application.c
@@ -815,12 +815,14 @@
 }
 
 GnmAppExtraUI *
-gnm_app_add_extra_ui (GSList *actions, char *layout,
+gnm_app_add_extra_ui (char const *group_name,
+		      GSList *actions, char *layout,
 		      char const *domain,
 		      gpointer user_data)
 {
 	GnmAppExtraUI *extra_ui = g_new0 (GnmAppExtraUI, 1);
 	extra_uis = g_slist_prepend (extra_uis, extra_ui);
+	extra_ui->group_name = g_strdup (group_name);
 	extra_ui->actions = actions;
 	extra_ui->layout = layout;
 	extra_ui->user_data = user_data;
@@ -832,6 +834,8 @@
 gnm_app_remove_extra_ui (GnmAppExtraUI *extra_ui)
 {
 	g_signal_emit (G_OBJECT (app), signals [CUSTOM_UI_REMOVED], 0, extra_ui);
+	g_free (extra_ui->group_name);
+	g_free (extra_ui);
 }
 
 void

