From 99bb3eba4018f7e0c3e048fa439cc9d3bfb2d1d6 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 3 Dec 2009 10:22:45 +0200 Subject: Fail when trying to extract negative value to unsigned type The standard iostream behavior requires such an extraction to succeed. Because of that we weren't detecting some invalid value. --- libxsd/xsd/cxx/zc-istream.hxx | 125 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/libxsd/xsd/cxx/zc-istream.hxx b/libxsd/xsd/cxx/zc-istream.hxx index 2f0c1ed..c82d437 100644 --- a/libxsd/xsd/cxx/zc-istream.hxx +++ b/libxsd/xsd/cxx/zc-istream.hxx @@ -68,6 +68,8 @@ namespace xsd class zc_istream: protected zc_istream_base, public std::basic_istream { + typedef std::basic_istream base; + public: zc_istream (const ro_string&); zc_istream (const std::basic_string&); @@ -78,6 +80,129 @@ namespace xsd return this->get () == std::basic_istream::traits_type::eof (); } + zc_istream& + operator>> (unsigned char& x) + { + if (check_unsigned ()) + static_cast (*this) >> x; + + return *this; + } + + zc_istream& + operator>> (signed char& x) + { + if (check_signed ()) + static_cast (*this) >> x; + + return *this; + } + + zc_istream& + operator>> (unsigned short& x) + { + if (check_unsigned ()) + static_cast (*this) >> x; + + return *this; + } + + zc_istream& + operator>> (short& x) + { + if (check_signed ()) + static_cast (*this) >> x; + + return *this; + } + + zc_istream& + operator>> (unsigned int& x) + { + if (check_unsigned ()) + static_cast (*this) >> x; + + return *this; + } + + zc_istream& + operator>> (int& x) + { + if (check_signed ()) + static_cast (*this) >> x; + + return *this; + } + + zc_istream& + operator>> (unsigned long& x) + { + if (check_unsigned ()) + static_cast (*this) >> x; + + return *this; + } + + zc_istream& + operator>> (long& x) + { + if (check_signed ()) + static_cast (*this) >> x; + + return *this; + } + + zc_istream& + operator>> (unsigned long long& x) + { + if (check_unsigned ()) + static_cast (*this) >> x; + + return *this; + } + + zc_istream& + operator>> (long long& x) + { + if (check_signed ()) + static_cast (*this) >> x; + + return *this; + } + + template + zc_istream& + operator>> (X& x) + { + static_cast (*this) >> x; + return *this; + } + + private: + bool + check_signed () + { + typename std::basic_istream::traits_type::int_type p (this->peek ()); + bool r ((p >= C ('0') && p <= C ('9')) || p == C ('-') || p == C ('+')); + + if (!r) + this->setstate (std::ios_base::failbit); + + return r; + } + + bool + check_unsigned () + { + typename std::basic_istream::traits_type::int_type p (this->peek ()); + bool r ((p >= C ('0') && p <= C ('9')) || p == C ('+')); + + if (!r) + this->setstate (std::ios_base::failbit); + + return r; + } + private: zc_istream (const zc_istream&); -- cgit v1.1