From 8f51615aa7c8cab8137c82e89446928e3632dc74 Mon Sep 17 00:00:00 2001
From: Richard Linden <none@none>
Date: Thu, 16 Sep 2010 00:41:27 -0700
Subject: [PATCH] fixed serialization of choice blocks sometimes including more
 than one alternative fixed deserialization of Multiple<Block> leaving dummy
 blocks around when failing to find matching key

---
 indra/llxuixml/llinitparam.cpp |  2 +-
 indra/llxuixml/llinitparam.h   | 25 ++++++++++++++++++++-----
 2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp
index 7b6be55ec7b..dc4d93d38af 100644
--- a/indra/llxuixml/llinitparam.cpp
+++ b/indra/llxuixml/llinitparam.cpp
@@ -178,7 +178,7 @@ namespace LLInitParam
 			param_handle_t param_handle = it->second->mParamHandle;
 			const Param* param = getParamFromHandle(param_handle);
 			ParamDescriptor::serialize_func_t serialize_func = it->second->mSerializeFunc;
-			if (serialize_func)
+			if (serialize_func && param->getProvided())
 			{
 				// Ensure this param has not already been serialized
 				// Prevents <rect> from being serialized as its own tag.
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 2d281dd0b88..610381dcfe9 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -1101,24 +1101,28 @@ namespace LLInitParam
 		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation) 
 		{ 
 			self_t& typed_param = static_cast<self_t&>(param);
+			bool new_value = false;
 			if (generation != typed_param.mLastParamGeneration || typed_param.mValues.empty())
 			{
+				new_value = true;
 				typed_param.mValues.push_back(value_t());
 				typed_param.mCachedKeys.push_back(Data());
-				typed_param.enclosingBlock().setLastChangedParam(param, true);
-				typed_param.mLastParamGeneration = generation;
 			}
 
-			value_t& value = typed_param.mValues.back();
+			value_ref_t value = typed_param.mValues.back();
 
 			// attempt to parse block...
 			if(value.deserializeBlock(parser, name_stack))
 			{
+				if (new_value)
+				{	// successfully parsed new value, let's keep it
+					typed_param.mLastParamGeneration = generation;
+				}
+				typed_param.enclosingBlock().setLastChangedParam(param, true);
 				typed_param.setProvided(true);
 				return true;
 			}
-
-			if(!NAME_VALUE_LOOKUP::empty())
+			else if(!NAME_VALUE_LOOKUP::empty())
 			{
 				// try to parse a known named value
 				std::string name;
@@ -1127,6 +1131,11 @@ namespace LLInitParam
 					// try to parse a per type named value
 					if (NAME_VALUE_LOOKUP::get(name, value))
 					{
+						if (new_value)
+						{	// successfully parsed new value, let's keep it
+							typed_param.mLastParamGeneration = generation;
+						}
+
 						typed_param.mCachedKeys.back().setKey(name);
 						typed_param.mCachedKeys.back().mKeyVersion = value.getLastChangeVersion();
 						typed_param.enclosingBlock().setLastChangedParam(param, true);
@@ -1137,6 +1146,12 @@ namespace LLInitParam
 				}
 			}
 
+			if (new_value)
+			{	// failed to parse new value, pop it off
+				typed_param.mValues.pop_back();
+				typed_param.mCachedKeys.pop_back();
+			}
+
 			return false;
 		}
 
-- 
GitLab