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/pugixpath.cpp | |
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/pugixpath.cpp')
-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(); |