From 60f93645aa2d5bd5d29da158fd3d90c317c39a64 Mon Sep 17 00:00:00 2001
From: Kitty Barnett <develop@catznip.com>
Date: Sat, 4 Jun 2016 14:58:00 +0200
Subject: [PATCH] [FIXED] RlvHandler::hasBehaviourExcept() returns FALSE on
 modifier commands   -> Example: issue @tplocal:50=n   ->
 gRlvHandler.hasBehaviour(RLV_BHVR_TPLOCAL) will return true but
 gRlvHandler.hasBehaviourExcept(RLV_BHVR_TPLOCAL, LLUUID::null) will return
 FALSE   => since it's a modifier command it will be reference counted but
 that fact is lost on manual matching (tplocal=n != tplocal:<option>=n) so we
 keep track of reference counting in the command

--HG--
branch : RLVa
---
 indra/newview/rlvhandler.cpp |  2 ++
 indra/newview/rlvhelper.cpp  | 14 ++++++++++++--
 indra/newview/rlvhelper.h    |  4 ++++
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp
index c1c4b7d8073..cbd54958e50 100644
--- a/indra/newview/rlvhandler.cpp
+++ b/indra/newview/rlvhandler.cpp
@@ -1251,6 +1251,7 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd)
 			if (rlvCmd.isStrict())
 				addException(rlvCmd.getObjectID(), RLV_BHVR_PERMISSIVE, eBhvr);
 			m_Behaviours[eBhvr]++;
+			rlvCmd.markRefCounted();
 		}
 		else
 		{
@@ -1283,6 +1284,7 @@ ERlvCmdRet RlvCommandHandlerBaseImpl<RLV_TYPE_ADDREM>::processCommand(const RlvC
 			if (rlvCmd.isStrict())
 				gRlvHandler.addException(rlvCmd.getObjectID(), RLV_BHVR_PERMISSIVE, eBhvr);
 			gRlvHandler.m_Behaviours[eBhvr]++;
+			rlvCmd.markRefCounted();
 		}
 		else
 		{
diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp
index 4a4d8356b3f..d8baee2adf9 100644
--- a/indra/newview/rlvhelper.cpp
+++ b/indra/newview/rlvhelper.cpp
@@ -860,9 +860,19 @@ bool RlvObject::hasBehaviour(ERlvBehaviour eBehaviour, bool fStrictOnly) const
 
 bool RlvObject::hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOption, bool fStrictOnly) const
 {
-	for (rlv_command_list_t::const_iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd)
-		if ( (itCmd->getBehaviourType() == eBehaviour) && (itCmd->getOption() == strOption) && ((!fStrictOnly) || (itCmd->isStrict())) )
+	for (const RlvCommand& rlvCmd : m_Commands)
+	{
+		// The specified behaviour is contained within the current object if:
+		//   - the (parsed) behaviour matches
+		//   - the option matches (or we're checking for an empty option and the command was reference counted)
+		//   - we're not matching on strict (or it is a strict command)
+		if ( (rlvCmd.getBehaviourType() == eBehaviour) &&
+			 ( (rlvCmd.getOption() == strOption) || ((strOption.empty()) && (rlvCmd.isRefCounted())) ) &&
+			 ( (!fStrictOnly) ||(rlvCmd.isStrict()) ) )
+		{
 			return true;
+		}
+	}
 	return false;
 }
 
diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h
index cfe64a48f52..41daab13603 100644
--- a/indra/newview/rlvhelper.h
+++ b/indra/newview/rlvhelper.h
@@ -369,12 +369,14 @@ class RlvCommand
 	ERlvCmdRet         getReturnType() const	{ return m_eRet; }
 	bool               hasOption() const		{ return !m_strOption.empty(); }
 	bool               isBlocked() const        { return (m_pBhvrInfo) ? m_pBhvrInfo->isBlocked() : false; }
+	bool               isRefCounted() const     { return m_fRefCounted; }
 	bool               isStrict() const			{ return m_fStrict; }
 	bool               isValid() const			{ return m_fValid; }
 	ERlvCmdRet         processCommand() const   { return (m_pBhvrInfo) ? m_pBhvrInfo->processCommand(*this) : RLV_RET_NO_PROCESSOR; }
 
 protected:
 	static bool parseCommand(const std::string& strCommand, std::string& strBehaviour, std::string& strOption,  std::string& strParam);
+	bool               markRefCounted() const   { return m_fRefCounted = true; }
 
 	/*
 	 * Operators
@@ -395,9 +397,11 @@ class RlvCommand
 	std::string             m_strOption;
 	std::string             m_strParam;
 	ERlvCmdRet              m_eRet;
+	mutable bool            m_fRefCounted;
 
 	friend class RlvHandler;
 	friend class RlvObject;
+	template<ERlvParamType> friend struct RlvCommandHandlerBaseImpl;
 };
 
 // ============================================================================
-- 
GitLab