diff options
| author | Nat Goodspeed <nat@lindenlab.com> | 2011-07-12 14:34:31 -0400 | 
|---|---|---|
| committer | Nat Goodspeed <nat@lindenlab.com> | 2011-07-12 14:34:31 -0400 | 
| commit | e58a0e9b26dc374155b90a8f42c3a5b09e8ed1f7 (patch) | |
| tree | 4ce7028bfd494965c1a98ae77b0b6da540680110 /indra/llcommon | |
| parent | 4e2355036358ed712dd7df2668ec705931ad13a1 (diff) | |
CHOP-753: Defend against boost::regex exceptions.
(per Monty code review)
Explain why we intentionally don't suppress exceptions from boost::regex
objects constructed with string literals. Catch std::runtime_error from
boost::regex_search() and boost::regex_match(); log and return false.
Diffstat (limited to 'indra/llcommon')
| -rw-r--r-- | indra/llcommon/llsys.cpp | 50 | 
1 files changed, 46 insertions, 4 deletions
| diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index aa71590eae..ebdef56c2a 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -70,11 +70,13 @@ using namespace llsd;  #	include <Carbon/Carbon.h>  #   include <sys/wait.h>  #   include <string.h> +#   include <stdexcept>  #elif LL_LINUX  #	include <errno.h>  #	include <sys/utsname.h>  #	include <unistd.h>  #	include <sys/sysinfo.h> +#   include <stdexcept>  const char MEMINFO_FILE[] = "/proc/meminfo";  #elif LL_SOLARIS  #	include <stdio.h> @@ -682,6 +684,38 @@ private:  	LLSD mStats;  }; +// Wrap boost::regex_match() with a function that doesn't throw. +template <typename S, typename M, typename R> +static bool regex_match_no_exc(const S& string, M& match, const R& regex) +{ +    try +    { +        return boost::regex_match(string, match, regex); +    } +    catch (const std::runtime_error& e) +    { +        LL_WARNS("LLMemoryInfo") << "error matching with '" << regex.str() << "': " +                                 << e.what() << ":\n'" << string << "'" << LL_ENDL; +        return false; +    } +} + +// Wrap boost::regex_search() with a function that doesn't throw. +template <typename S, typename M, typename R> +static bool regex_search_no_exc(const S& string, M& match, const R& regex) +{ +    try +    { +        return boost::regex_search(string, match, regex); +    } +    catch (const std::runtime_error& e) +    { +        LL_WARNS("LLMemoryInfo") << "error searching with '" << regex.str() << "': " +                                 << e.what() << ":\n'" << string << "'" << LL_ENDL; +        return false; +    } +} +  LLMemoryInfo::LLMemoryInfo()  {  	refresh(); @@ -1012,6 +1046,10 @@ LLSD LLMemoryInfo::loadStatsArray()  		// Pageouts:					  41759.  		// Object cache: 841598 hits of 7629869 lookups (11% hit rate) +		// Intentionally don't pass the boost::no_except flag. These +		// boost::regex objects are constructed with string literals, so they +		// should be valid every time. If they become invalid, we WANT an +		// exception, hopefully even before the dev checks in.  		boost::regex pagesize_rx("\\(page size of ([0-9]+) bytes\\)");  		boost::regex stat_rx("(.+): +([0-9]+)\\.");  		boost::regex cache_rx("Object cache: ([0-9]+) hits of ([0-9]+) lookups " @@ -1031,7 +1069,7 @@ LLSD LLMemoryInfo::loadStatsArray()  				line[--linelen] = '\0';  			}  			LL_DEBUGS("LLMemoryInfo") << line << LL_ENDL; -			if (boost::regex_search(line, matched, pagesize_rx)) +			if (regex_search_no_exc(line, matched, pagesize_rx))  			{  				// "Mach Virtual Memory Statistics: (page size of 4096 bytes)"  				std::string pagesize_str(matched[1].first, matched[1].second); @@ -1049,7 +1087,7 @@ LLSD LLMemoryInfo::loadStatsArray()  				}  				stats.add("page size", pagesizekb);  			} -			else if (boost::regex_match(line, matched, stat_rx)) +			else if (regex_match_no_exc(line, matched, stat_rx))  			{  				// e.g. "Pages free:					 462078."  				// Strip double-quotes off certain statistic names @@ -1084,7 +1122,7 @@ LLSD LLMemoryInfo::loadStatsArray()  					stats.add(kbkey, value * pagesizekb);  				}  			} -			else if (boost::regex_match(line, matched, cache_rx)) +			else if (regex_match_no_exc(line, matched, cache_rx))  			{  				// e.g. "Object cache: 841598 hits of 7629869 lookups (11% hit rate)"  				static const char* cache_keys[] = { "cache hits", "cache lookups", "cache hit%" }; @@ -1185,6 +1223,10 @@ LLSD LLMemoryInfo::loadStatsArray()  		// DirectMap4k:		 434168 kB  		// DirectMap2M:		 477184 kB +		// Intentionally don't pass the boost::no_except flag. This +		// boost::regex object is constructed with a string literal, so it +		// should be valid every time. If it becomes invalid, we WANT an +		// exception, hopefully even before the dev checks in.  		boost::regex stat_rx("(.+): +([0-9]+)( kB)?");  		boost::smatch matched; @@ -1192,7 +1234,7 @@ LLSD LLMemoryInfo::loadStatsArray()  		while (std::getline(meminfo, line))  		{  			LL_DEBUGS("LLMemoryInfo") << line << LL_ENDL; -			if (boost::regex_match(line, matched, stat_rx)) +			if (regex_match_no_exc(line, matched, stat_rx))  			{  				// e.g. "MemTotal:		4108424 kB"  				LLSD::String key(matched[1].first, matched[1].second); | 
