From: Lars Windolf <lars.lindner@gmail.com>
Date: Fri, 5 Oct 2012 12:09:42 +0200
Subject: [PATCH] Fixes SF #3572660: crash in google_source_remove_node (reported by Yanko Kaneti)
Origin: upstream, http://liferea.git.sourceforge.net/git/gitweb.cgi?p=liferea/liferea;a=commit;h=878863cd0e02e89e461e5e47f02be38e57a4fe27
Bug: http://sourceforge.net/tracker/index.php?func=detail&aid=3572660&group_id=87005&atid=581684
Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=692525
Last-Update: 2012-12-15
--- a/src/fl_sources/default_source.c
+++ b/src/fl_sources/default_source.c
@@ -210,6 +210,8 @@
 	.description		= "The default feed list source. Should never be added manually. If you see this then something went wrong!",
 	.capabilities		= NODE_SOURCE_CAPABILITY_IS_ROOT |
 				  NODE_SOURCE_CAPABILITY_HIERARCHIC_FEEDLIST |
+	                          NODE_SOURCE_CAPABILITY_ADD_FEED |
+	                          NODE_SOURCE_CAPABILITY_ADD_FOLDER |
 				  NODE_SOURCE_CAPABILITY_WRITABLE_FEEDLIST,
 	.source_type_init	= default_source_init,
 	.source_type_deinit	= default_source_deinit,
--- a/src/fl_sources/node_source.h
+++ b/src/fl_sources/node_source.h
@@ -50,11 +50,12 @@
 
 enum {
 	NODE_SOURCE_CAPABILITY_IS_ROOT			= (1<<0),	/**< flag only for default feed list source */
-	NODE_SOURCE_CAPABILITY_MULTI_INSTANCES		= (1<<1),	/**< allows multiple source instances */
-	NODE_SOURCE_CAPABILITY_DYNAMIC_CREATION		= (1<<2),	/**< feed list source is user created */
-	NODE_SOURCE_CAPABILITY_WRITABLE_FEEDLIST	= (1<<3),	/**< the feed list tree of the source can be changed */
-	NODE_SOURCE_CAPABILITY_HIERARCHIC_FEEDLIST	= (1<<4),	/**< the feed list tree of the source can have hierarchic folders */
-	NODE_SOURCE_CAPABILITY_ITEM_STATE_SYNC		= (1<<5)	/**< the item state can and should be sync'ed with remote */
+	NODE_SOURCE_CAPABILITY_DYNAMIC_CREATION		= (1<<1),	/**< feed list source is user created */
+	NODE_SOURCE_CAPABILITY_WRITABLE_FEEDLIST	= (1<<2),	/**< the feed list tree of the source can be changed */
+	NODE_SOURCE_CAPABILITY_ADD_FEED			= (1<<3),	/**< feeds can be added to the source */
+	NODE_SOURCE_CAPABILITY_ADD_FOLDER		= (1<<4),	/**< folders can be added to the source */
+	NODE_SOURCE_CAPABILITY_HIERARCHIC_FEEDLIST	= (1<<5),	/**< the feed list tree of the source can have hierarchic folders */
+	NODE_SOURCE_CAPABILITY_ITEM_STATE_SYNC		= (1<<6)	/**< the item state can and should be sync'ed with remote */
 };
 
 /** feed list node source type */
--- a/src/node.c
+++ b/src/node.c
@@ -494,6 +494,28 @@
 	return baseUrl;
 }
 
+gboolean
+node_can_add_child_feed (nodePtr node)
+{
+	g_assert (node->source->root);
+
+	if (!(NODE_TYPE (node->source->root)->capabilities & NODE_CAPABILITY_ADD_CHILDS))
+		return FALSE;
+
+	return (NODE_SOURCE_TYPE (node)->capabilities & NODE_SOURCE_CAPABILITY_ADD_FEED);
+}
+
+gboolean
+node_can_add_child_folder (nodePtr node)
+{
+	g_assert (node->source->root);
+
+	if (!(NODE_TYPE (node->source->root)->capabilities & NODE_CAPABILITY_ADD_CHILDS))
+		return FALSE;
+
+	return (NODE_SOURCE_TYPE (node)->capabilities & NODE_SOURCE_CAPABILITY_ADD_FOLDER);
+}
+
 /* node children iterating interface */
 
 void
--- a/src/node.h
+++ b/src/node.h
@@ -355,6 +355,24 @@
  */
 const gchar * node_get_base_url(nodePtr node);
 
+/**
+ * Query wether a feed be added to the given node.
+ *
+ * @param node	the node
+ *
+ * @returns TRUE if a feed can be added
+ */
+gboolean node_can_add_child_feed (nodePtr node);
+
+/**
+ * Query wether a folder be added to the given node.
+ *
+ * @param node	the node
+ *
+ * @returns TRUE if a folder can be added
+ */
+gboolean node_can_add_child_folder (nodePtr node);
+
 /* child nodes iterating interface */
 
 typedef void 	(*nodeActionFunc)	(nodePtr node);
--- a/src/ui/popup_menu.c
+++ b/src/ui/popup_menu.c
@@ -262,14 +262,15 @@
 ui_popup_node_menu (nodePtr node, gboolean validSelection, guint button, guint32 activate_time)
 {
 	GtkWidget	*menu;
-	gboolean	writeableFeedlist, isRoot, isHierarchic;
+	gboolean	writeableFeedlist, isRoot, isHierarchic, addChildren;
 
 	menu = gtk_menu_new ();
 	
 	if (node->parent) {
 		writeableFeedlist = NODE_SOURCE_TYPE (node->parent->source->root)->capabilities & NODE_SOURCE_CAPABILITY_WRITABLE_FEEDLIST;
-		isRoot = NODE_SOURCE_TYPE (node->parent->source->root)->capabilities & NODE_SOURCE_CAPABILITY_IS_ROOT;
+		isRoot = NODE_SOURCE_TYPE (node->source->root)->capabilities & NODE_SOURCE_CAPABILITY_IS_ROOT;
 		isHierarchic = NODE_SOURCE_TYPE (node->parent->source->root)->capabilities & NODE_SOURCE_CAPABILITY_HIERARCHIC_FEEDLIST;
+		addChildren = NODE_TYPE (node->source->root)->capabilities & NODE_CAPABILITY_ADD_CHILDS;
 	} else {
 		/* if we have no parent then we have the root node... */
 		writeableFeedlist = TRUE;
@@ -287,7 +288,7 @@
 	}
 
 	if (writeableFeedlist) {
-		if (NODE_TYPE (node->source->root)->capabilities & NODE_CAPABILITY_ADD_CHILDS) {
+		if (addChildren) {
 			GtkWidget	*item;
 			GtkWidget	*submenu;
 
@@ -295,9 +296,10 @@
 
 			item = ui_popup_add_menuitem (menu, _("_New"), NULL, NULL, NULL, 0);
 
-			ui_popup_add_menuitem (submenu, _("New _Subscription..."), ui_popup_add_feed, NULL, NULL, 0);
+			if (node_can_add_child_feed (node))
+				ui_popup_add_menuitem (submenu, _("New _Subscription..."), ui_popup_add_feed, NULL, NULL, 0);
 			
-			if (isHierarchic)
+			if (node_can_add_child_folder (node))
 				ui_popup_add_menuitem (submenu, _("New _Folder..."), ui_popup_add_folder, NULL, NULL, 0);
 				
 			if (isRoot) {
@@ -309,7 +311,7 @@
 			gtk_menu_item_set_submenu (GTK_MENU_ITEM(item), submenu);
 		}
 		
-		if (node->children) {
+		if (isRoot && node->children) {
 			gtk_menu_shell_append (GTK_MENU_SHELL(menu), gtk_separator_menu_item_new());
 			ui_popup_add_menuitem (menu, _("Sort Feeds"), ui_popup_sort_feeds, node, GTK_STOCK_SORT_ASCENDING, 0);
 		}
--- a/src/fl_sources/google_source.c
+++ b/src/fl_sources/google_source.c
@@ -360,6 +360,7 @@
 	   "present your Google Reader subscriptions, and will synchronize your feed list and reading lists."),
 	.capabilities        = NODE_SOURCE_CAPABILITY_DYNAMIC_CREATION | 
 	                       NODE_SOURCE_CAPABILITY_WRITABLE_FEEDLIST |
+	                       NODE_SOURCE_CAPABILITY_ADD_FEED |
 	                       NODE_SOURCE_CAPABILITY_ITEM_STATE_SYNC,
 	.source_type_init    = google_source_init,
 	.source_type_deinit  = google_source_deinit,
