summaryrefslogtreecommitdiff
path: root/include/locale
diff options
context:
space:
mode:
authorDimitry Andric <dimitry@andric.com>2017-05-06 20:58:50 +0000
committerDimitry Andric <dimitry@andric.com>2017-05-06 20:58:50 +0000
commit2f214595bc6e074c3945ae96fe76604788aa4910 (patch)
tree7edcb69c206bfffcd9eb6106a1959e0cb99f77e7 /include/locale
parenta9f9f0b205227ee69093d550b8c6e98f72c75a9e (diff)
Ensure showbase does not overflow do_put buffers
Summary: In https://bugs.freebsd.org/207918, Daniel McRobb describes how using std::showbase with ostreams can cause truncation of unsigned long long when output format is octal. In fact, this can even happen with unsigned int and unsigned long. To ensure this does not happen, add one additional character to the do_put buffers if std::showbase is on. Also add a test case. Reviewers: EricWF, mclow.lists Reviewed By: EricWF Subscribers: cfe-commits, emaste Differential Revision: https://reviews.llvm.org/D32670 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@302362 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/locale')
-rw-r--r--include/locale4
1 files changed, 4 insertions, 0 deletions
diff --git a/include/locale b/include/locale
index d0909d58c..f0e1c3b82 100644
--- a/include/locale
+++ b/include/locale
@@ -1402,6 +1402,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
this->__format_int(__fmt+1, __len, true, __iob.flags());
const unsigned __nbuf = (numeric_limits<long>::digits / 3)
+ ((numeric_limits<long>::digits % 3) != 0)
+ + ((__iob.flags() & ios_base::showbase) != 0)
+ 2;
char __nar[__nbuf];
int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
@@ -1428,6 +1429,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
this->__format_int(__fmt+1, __len, true, __iob.flags());
const unsigned __nbuf = (numeric_limits<long long>::digits / 3)
+ ((numeric_limits<long long>::digits % 3) != 0)
+ + ((__iob.flags() & ios_base::showbase) != 0)
+ 2;
char __nar[__nbuf];
int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
@@ -1454,6 +1456,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
this->__format_int(__fmt+1, __len, false, __iob.flags());
const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3)
+ ((numeric_limits<unsigned long>::digits % 3) != 0)
+ + ((__iob.flags() & ios_base::showbase) != 0)
+ 1;
char __nar[__nbuf];
int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);
@@ -1480,6 +1483,7 @@ num_put<_CharT, _OutputIterator>::do_put(iter_type __s, ios_base& __iob,
this->__format_int(__fmt+1, __len, false, __iob.flags());
const unsigned __nbuf = (numeric_limits<unsigned long long>::digits / 3)
+ ((numeric_limits<unsigned long long>::digits % 3) != 0)
+ + ((__iob.flags() & ios_base::showbase) != 0)
+ 1;
char __nar[__nbuf];
int __nc = __libcpp_snprintf_l(__nar, sizeof(__nar), _LIBCPP_GET_C_LOCALE, __fmt, __v);