diff options
| author | arseny.kapoulkine <arseny.kapoulkine@99668b35-9821-0410-8761-19e4c4f06640> | 2010-08-29 15:16:55 +0000 | 
|---|---|---|
| committer | arseny.kapoulkine <arseny.kapoulkine@99668b35-9821-0410-8761-19e4c4f06640> | 2010-08-29 15:16:55 +0000 | 
| commit | 1f74bf1edcae00bd33a2ecbcd9838b4d98f810b2 (patch) | |
| tree | e1215cc781a7e6dacf60b969660a52db1971c2a6 /src | |
| parent | 6a9d59e90717c3ce8eae19e562b01c4125934681 (diff) | |
XPath: Correct out of memory handling for string to number conversion during parsing, added corresponding test
git-svn-id: http://pugixml.googlecode.com/svn/trunk@651 99668b35-9821-0410-8761-19e4c4f06640
Diffstat (limited to 'src')
| -rw-r--r-- | src/pugixpath.cpp | 36 | 
1 files changed, 17 insertions, 19 deletions
diff --git a/src/pugixpath.cpp b/src/pugixpath.cpp index 1e20d8c..d67eac6 100644 --- a/src/pugixpath.cpp +++ b/src/pugixpath.cpp @@ -497,35 +497,30 @@ namespace  	#endif  	} -	double convert_string_to_number(const char_t* begin, const char_t* end) +	bool convert_string_to_number(const char_t* begin, const char_t* end, double* out_result)  	{  		char_t buffer[32];  		size_t length = static_cast<size_t>(end - begin); +		char_t* scratch = buffer; -		if (length < sizeof(buffer) / sizeof(buffer[0])) -		{ -			// optimized on-stack conversion -			memcpy(buffer, begin, length * sizeof(char_t)); -			buffer[length] = 0; - -			return convert_string_to_number(buffer); -		} -		else +		if (length >= sizeof(buffer) / sizeof(buffer[0]))  		{  			// need to make dummy on-heap copy -			char_t* copy = static_cast<char_t*>(get_memory_allocation_function()((length + 1) * sizeof(char_t))); -			if (!copy) return gen_nan(); // $$ out of memory +			scratch = static_cast<char_t*>(get_memory_allocation_function()((length + 1) * sizeof(char_t))); +			if (!scratch) return false; +		} -			memcpy(copy, begin, length * sizeof(char_t)); -			copy[length] = 0; +		// copy string to zero-terminated buffer and perform conversion +		memcpy(scratch, begin, length * sizeof(char_t)); +		scratch[length] = 0; -			double result = convert_string_to_number(copy); +		*out_result = convert_string_to_number(scratch); -			get_memory_deallocation_function()(copy); +		// free dummy buffer +		if (scratch != buffer) get_memory_deallocation_function()(scratch); -			return result; -		} +		return true;  	}  	double round_nearest(double value) @@ -2899,7 +2894,10 @@ namespace pugi  			case lex_number:  			{ -				double value = convert_string_to_number(_lexer.contents().begin, _lexer.contents().end); +				double value = 0; + +				if (!convert_string_to_number(_lexer.contents().begin, _lexer.contents().end, &value)) +					throw_error("Out of memory");  				xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_number_constant, xpath_type_number, value);  				_lexer.next();  | 
