From 9ebf1fd3b7aa84cad2824906c336ea678433a3f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=BCrgen=20Doser?= <jurgen.doser@gmail.com>
Date: Fri, 1 Feb 2013 15:50:33 +0100
Subject: [PATCH] Remove use of operator[] on a std::map, so no spurious
 elements get inserted. (fixes #464)

All uses of operator[] in guiConfigureWorld.cpp have been replaced
with .find() operations.

In some places, operator[] had been called with mod names of "Add-Ons"
or "N/A", which would insert a default-constructed ModSpec into the
list of add-on mods. In other places, the use of operator[] was safe
now, but it probably is safer for future changes to use .find()
everywhere.
---
 src/guiConfigureWorld.cpp | 83 ++++++++++++++++++++++++---------------
 1 file changed, 51 insertions(+), 32 deletions(-)

diff --git a/src/guiConfigureWorld.cpp b/src/guiConfigureWorld.cpp
index 38f1a554d..fdcd0d3e8 100644
--- a/src/guiConfigureWorld.cpp
+++ b/src/guiConfigureWorld.cpp
@@ -414,8 +414,9 @@ bool GUIConfigureWorld::OnEvent(const SEvent& event)
 				else if(selected_node != NULL && selected_node->getText() != NULL)
 				{  
 					std::string modname = wide_to_narrow(selected_node->getText());
-					ModSpec mod = m_addonmods[modname];
-					enableAllMods(mod.modpack_content,true);
+					std::map<std::string, ModSpec>::iterator mod_it = m_addonmods.find(modname);
+					if(mod_it != m_addonmods.end())
+						enableAllMods(mod_it->second.modpack_content,true);
 				}
 				return true;
 			}
@@ -427,8 +428,9 @@ bool GUIConfigureWorld::OnEvent(const SEvent& event)
 				if(selected_node != NULL && selected_node->getText() != NULL)
 				{
 					std::string modname = wide_to_narrow(selected_node->getText());
-					ModSpec mod = m_addonmods[modname];
-					enableAllMods(mod.modpack_content,false);
+					std::map<std::string, ModSpec>::iterator mod_it = m_addonmods.find(modname);
+					if(mod_it != m_addonmods.end())
+						enableAllMods(mod_it->second.modpack_content,false);
 				}
 				return true;
 			}
@@ -446,7 +448,7 @@ bool GUIConfigureWorld::OnEvent(const SEvent& event)
 			return true;
 		}
 		if(event.GUIEvent.EventType==gui::EGET_TREEVIEW_NODE_SELECT &&
-			event.GUIEvent.Caller->getID() == GUI_ID_MOD_TREEVIEW)
+		   event.GUIEvent.Caller->getID() == GUI_ID_MOD_TREEVIEW)
 		{
 			selecting_dep = -1;
 			selecting_rdep = -1;
@@ -560,42 +562,49 @@ void GUIConfigureWorld::adjustSidebar()
 		modname_w = L"N/A";
 	std::string modname = wide_to_narrow(modname_w);
 
-	// if no mods installed, don't show buttons or checkbox on the sidebar
+	ModSpec mspec;
+	std::map<std::string, ModSpec>::iterator it = m_addonmods.find(modname);
+	if(it != m_addonmods.end())
+		mspec = it->second;
+
+	m_dependencies_listbox->clear();
+	m_rdependencies_listbox->clear();
+
+	// if no mods installed, there is nothing to enable/disable, so we
+	// don't show buttons or checkbox on the sidebar
 	if(node->getParent() == m_treeview->getRoot() && !node->hasChilds())
 	{
 		m_disableall->setVisible(false);
 		m_enableall->setVisible(false);
 		m_enabled_checkbox->setVisible(false);
+		return;
 	} 
-	else
+	
+    // a modpack is not enabled/disabled by itself, only its cotnents
+    // are. so we show show enable/disable all buttons, but hide the
+    // checkbox
+	if(node->getParent() == m_treeview->getRoot() ||
+	   mspec.is_modpack)
 	{
-		// if modpack, show enable/disable all buttons. otherwise, show
-		// enabled checkbox
-		if(node->getParent() == m_treeview->getRoot() ||
-		   m_addonmods[modname].is_modpack)
-		{
-			m_enabled_checkbox->setVisible(false);
-			m_disableall->setVisible(true);
-			m_enableall->setVisible(true);
-			m_modname_text->setText((L"Modpack: "+modname_w).c_str());
-		}	
-		else	
-		{
-			m_disableall->setVisible(false);
-			m_enableall->setVisible(false);
-			m_enabled_checkbox->setVisible(true);
-			m_modname_text->setText((L"Mod: "+modname_w).c_str());
-		}
-	}
+		m_enabled_checkbox->setVisible(false);
+		m_disableall->setVisible(true);
+		m_enableall->setVisible(true);
+		m_modname_text->setText((L"Modpack: "+modname_w).c_str());
+		return;
+	}	
+
+	// for a normal mod, we hide the enable/disable all buttons, but show the checkbox.
+	m_disableall->setVisible(false);
+	m_enableall->setVisible(false);
+	m_enabled_checkbox->setVisible(true);
+	m_modname_text->setText((L"Mod: "+modname_w).c_str());
+
 	// the mod is enabled unless it is disabled in the world.mt settings. 
 	bool mod_enabled = true;
 	if(m_settings.exists("load_mod_"+modname))
 		mod_enabled = m_settings.getBool("load_mod_"+modname);
 	m_enabled_checkbox->setChecked(mod_enabled);
 
-	// dependencies of this mod:
-	m_dependencies_listbox->clear();
-	ModSpec mspec = m_addonmods[modname];
 	for(std::set<std::string>::iterator it=mspec.depends.begin();
 		it != mspec.depends.end(); ++it)
 	{
@@ -611,9 +620,7 @@ void GUIConfigureWorld::adjustSidebar()
 		m_dependencies_listbox->addItem(narrow_to_wide(dependency).c_str());
 	}
 
-
 	// reverse dependencies of this mod:
-	m_rdependencies_listbox->clear();
 	std::pair< std::multimap<std::string, std::string>::iterator, 
 			std::multimap<std::string, std::string>::iterator > rdep = 
 		m_reverse_depends.equal_range(modname);
@@ -639,19 +646,25 @@ void GUIConfigureWorld::enableAllMods(std::map<std::string, ModSpec> mods,bool e
 			enableAllMods(mod.modpack_content,enable);
 		else // not a modpack
 			setEnabled(mod.name, enable);
+
 	}
 }
 
 void GUIConfigureWorld::enableMod(std::string modname)
 {
+	std::map<std::string, ModSpec>::iterator mod_it = m_addonmods.find(modname);
+	if(mod_it == m_addonmods.end()){
+		errorstream << "enableMod() called with invalid mod name \"" << modname << "\"" << std::endl;
+		return;
+	}
+	ModSpec mspec = mod_it->second;
 	m_settings.setBool("load_mod_"+modname,true);
 	std::map<std::string,gui::IGUITreeViewNode*>::iterator it = 
 		m_nodes.find(modname);
- 	if(it != m_nodes.end())
+	if(it != m_nodes.end())
 		(*it).second->setIcon(CHECKMARK_STR);
 	m_new_mod_names.erase(modname);
 	//also enable all dependencies
-	ModSpec mspec = m_addonmods[modname];
 	for(std::set<std::string>::iterator it=mspec.depends.begin();
 		it != mspec.depends.end(); ++it)
 	{
@@ -664,6 +677,12 @@ void GUIConfigureWorld::enableMod(std::string modname)
 
 void GUIConfigureWorld::disableMod(std::string modname)
 {
+	std::map<std::string, ModSpec>::iterator mod_it = m_addonmods.find(modname);
+	if(mod_it == m_addonmods.end()){
+		errorstream << "disableMod() called with invalid mod name \"" << modname << "\"" << std::endl;
+		return;
+	}
+
 	m_settings.setBool("load_mod_"+modname,false);
 	std::map<std::string,gui::IGUITreeViewNode*>::iterator it = 
 		m_nodes.find(modname);
-- 
GitLab