This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] PR libstdc++/70664 Set failbit and read zero on stream reading negative value into unsigned type


Hi,

Currently when a value is extracted from a stream into a unsigned type,
there is no test to check if the value is negative, in which case there
is an overflow and failbit is not set (the correct behavior would be to
read a zero and set failbit). This patch add a condition to check when
we are in this particular case, read a zero and set failbit accordingly.

Tested on x86_64-pc-linux-gnu with the program provided in the bug
report (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70664)

#include <iostream>
#include <sstream>

using namespace std;

template <typename T>
void test(const char * str)
{
	istringstream a(str);
	T i;

	a >> i;
	if (a.fail())
		cout << "Ok: " << i << "\n";
	else
		cout << "Bug: " << i << "\n";
}

int main(int argc, char *argv[])
{
	test<int>("2147483648");  // INT_MIN-1
	test<int>("-2147483649"); // INT_MAX+1
	test<unsigned>("4294967296");  // UINT_MAX+1
	test<unsigned>("-1");
	return 0;
}

Output without the patch:
Ok: 2147483647
Ok: -2147483648
Ok: 4294967295
Bug: 4294967295

With the patch:
Ok: 2147483647
Ok: -2147483648
Ok: 4294967295
Ok: 0



libstdc++-v3/ChangeLog:

2018-03-13  Jean-Baptiste Daval  <naarakah@crans.org>

	PR libstdc++/70664
        * locale_facets_fix.tcc: Test when extracting a negative value
into an unsigned type


 libstdc++-v3/include/bits/locale_facets.tcc | 5 +++++
 1 file changed, 5 insertions(+)

iff --git a/libstdc++-v3/include/bits/locale_facets.tcc
b/libstdc++-v3/include/bits/locale_facets.tcc
index 39da5766075..9bc06c2e558 100644
--- a/libstdc++-v3/include/bits/locale_facets.tcc
+++ b/libstdc++-v3/include/bits/locale_facets.tcc
@@ -571,6 +571,11 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL
            __v = 0;
            __err = ios_base::failbit;
          }
+       else if (__negative && !__num_traits::_is_signed)
+        {
+          __v = 0;
+          __err = ios_base::failbit;
+         }
        else if (__testoverflow)
          {
            if (__negative && __num_traits::__is_signed)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]