Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHoward Hinnant <hhinnant@apple.com>2013-03-08 23:06:24 +0400
committerHoward Hinnant <hhinnant@apple.com>2013-03-08 23:06:24 +0400
commit7e4844b35371bcfd5cdff688a9d7346f8e982211 (patch)
treeb97b8f41bf81f23b93cd97a8d27d3d892e80a9e6 /libcxx/include/locale
parent5085d9b27594224856be21d2a4507269a3920e2a (diff)
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/locale20
1 files changed, 13 insertions, 7 deletions
diff --git a/libcxx/include/locale b/libcxx/include/locale
index 39aba848c953..8f9a3b696404 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;