diff options
author | Howard Hinnant <hhinnant@apple.com> | 2013-03-08 19:06:24 +0000 |
---|---|---|
committer | Howard Hinnant <hhinnant@apple.com> | 2013-03-08 19:06:24 +0000 |
commit | 7e4844b35371bcfd5cdff688a9d7346f8e982211 (patch) | |
tree | b97b8f41bf81f23b93cd97a8d27d3d892e80a9e6 /libcxx/include/locale | |
parent | 5085d9b27594224856be21d2a4507269a3920e2a (diff) | |
download | bcm5719-llvm-7e4844b35371bcfd5cdff688a9d7346f8e982211.tar.gz bcm5719-llvm-7e4844b35371bcfd5cdff688a9d7346f8e982211.zip |
Parsing floating point numbers with very long precision was broken, and this patch fixes it. This fixes http://llvm.org/bugs/show_bug.cgi?id=15445.
llvm-svn: 176711
Diffstat (limited to 'libcxx/include/locale')
-rw-r--r-- | libcxx/include/locale | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/libcxx/include/locale b/libcxx/include/locale index 39aba848c95..8f9a3b69640 100644 --- a/libcxx/include/locale +++ b/libcxx/include/locale @@ -646,6 +646,8 @@ __num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __ex _CharT __decimal_point, _CharT __thousands_sep, const string& __grouping, unsigned* __g, unsigned*& __g_end, unsigned& __dc, _CharT* __atoms) { + if (__a_end-__a >= __num_get_buf_sz - 1) + return -1; if (__ct == __decimal_point) { if (!__in_units) @@ -673,23 +675,27 @@ __num_get<_CharT>::__stage2_float_loop(_CharT __ct, bool& __in_units, char& __ex char __x = __src[__f]; if (__x == '-' || __x == '+') { - if (__a_end == __a || (__a_end[-1] & 0xDF) == __exp) + if (__a_end == __a || (__a_end[-1] & 0x5F) == (__exp & 0x7F)) { *__a_end++ = __x; return 0; } return -1; } - if (__a_end-__a < __num_get_buf_sz - 1) - *__a_end++ = __x; if (__x == 'x' || __x == 'X') __exp = 'P'; - else if ((__x & 0xDF) == __exp) + else if ((__x & 0x5F) == __exp) { - __in_units = false; - if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz) - *__g_end++ = __dc; + __exp |= 0x80; + if (__in_units) + { + __in_units = false; + if (__grouping.size() != 0 && __g_end-__g < __num_get_buf_sz) + *__g_end++ = __dc; + } } + if (__a_end-__a < __num_get_buf_sz - ((__exp & 0x80) ? 1 : 11)) + *__a_end++ = __x; if (__f >= 22) return 0; ++__dc; |