Bugfix #109 (part 2): re-established compatibility with previous version.

This commit is contained in:
Matthias Koefferlein 2018-04-06 23:08:41 +02:00
parent ea3ebba470
commit 655eb49afd
4 changed files with 144 additions and 167 deletions

View File

@ -831,32 +831,61 @@ tl::Extractor::read_quoted (std::string &value)
return *this; return *this;
} }
bool namespace
tl::Extractor::try_read (unsigned int &value)
{ {
if (! *skip ()) { template <class T> struct overflow_msg_func;
return false;
}
if (! isdigit (*m_cp)) { template <> struct overflow_msg_func<long long>
return false; {
std::string operator() () const
{
return tl::to_string (QObject::tr ("Range overflow on long long integer"));
} }
};
value = 0; template <> struct overflow_msg_func<unsigned long long>
while (isdigit (*m_cp)) { {
if ((value * 10) / 10 != value) { std::string operator() () const
throw tl::Exception (tl::to_string (QObject::tr ("Range overflow on unsigned integer"))); {
} return tl::to_string (QObject::tr ("Range overflow on unsigned long long integer"));
value *= 10;
value += (*m_cp - '0');
++m_cp;
} }
};
return true; template <> struct overflow_msg_func<long>
{
std::string operator() () const
{
return tl::to_string (QObject::tr ("Range overflow on long integer"));
}
};
template <> struct overflow_msg_func<unsigned long>
{
std::string operator() () const
{
return tl::to_string (QObject::tr ("Range overflow on unsigned long integer"));
}
};
template <> struct overflow_msg_func<int>
{
std::string operator() () const
{
return tl::to_string (QObject::tr ("Range overflow on integer"));
}
};
template <> struct overflow_msg_func<unsigned int>
{
std::string operator() () const
{
return tl::to_string (QObject::tr ("Range overflow on unsigned integer"));
}
};
} }
bool template <class T> bool
tl::Extractor::try_read (int &value) tl::Extractor::try_read_signed_int (T &value)
{ {
if (! *skip ()) { if (! *skip ()) {
return false; return false;
@ -876,10 +905,13 @@ tl::Extractor::try_read (int &value)
value = 0; value = 0;
while (isdigit (*m_cp)) { while (isdigit (*m_cp)) {
if ((value * 10) / 10 != value) { if (value > std::numeric_limits<T>::max () / 10) {
throw tl::Exception (tl::to_string (QObject::tr ("Range overflow on integer"))); throw tl::Exception (overflow_msg_func<T> () ());
} }
value *= 10; value *= 10;
if (value > std::numeric_limits<T>::max () - (*m_cp - '0')) {
throw tl::Exception (overflow_msg_func<T> () ());
}
value += (*m_cp - '0'); value += (*m_cp - '0');
++m_cp; ++m_cp;
} }
@ -891,126 +923,68 @@ tl::Extractor::try_read (int &value)
return true; return true;
} }
template <class T> bool
tl::Extractor::try_read_unsigned_int (T &value)
{
if (! *skip ()) {
return false;
}
if (! isdigit (*m_cp)) {
return false;
}
value = 0;
while (isdigit (*m_cp)) {
if (value > std::numeric_limits<T>::max () / 10) {
throw tl::Exception (overflow_msg_func<T> () ());
}
value *= 10;
if (value > std::numeric_limits<T>::max () - (*m_cp - '0')) {
throw tl::Exception (overflow_msg_func<T> () ());
}
value += (*m_cp - '0');
++m_cp;
}
return true;
}
bool
tl::Extractor::try_read (unsigned int &value)
{
return try_read_unsigned_int (value);
}
bool bool
tl::Extractor::try_read (unsigned long &value) tl::Extractor::try_read (unsigned long &value)
{ {
if (! *skip ()) { return try_read_unsigned_int (value);
return false;
}
if (! isdigit (*m_cp)) {
return false;
}
value = 0;
while (isdigit (*m_cp)) {
if ((value * 10) / 10 != value) {
throw tl::Exception (tl::to_string (QObject::tr ("Range overflow on unsigned long integer")));
}
value *= 10;
value += (*m_cp - '0');
++m_cp;
}
return true;
} }
bool bool
tl::Extractor::try_read (unsigned long long &value) tl::Extractor::try_read (unsigned long long &value)
{ {
if (! *skip ()) { return try_read_unsigned_int (value);
return false; }
}
if (! isdigit (*m_cp)) { bool
return false; tl::Extractor::try_read (int &value)
} {
return try_read_signed_int (value);
value = 0;
while (isdigit (*m_cp)) {
if ((value * 10) / 10 != value) {
throw tl::Exception (tl::to_string (QObject::tr ("Range overflow on unsigned long long integer")));
}
value *= 10;
value += (*m_cp - '0');
++m_cp;
}
return true;
} }
bool bool
tl::Extractor::try_read (long &value) tl::Extractor::try_read (long &value)
{ {
if (! *skip ()) { return try_read_signed_int (value);
return false;
}
bool minus = false;
if (*m_cp == '-') {
minus = true;
++m_cp;
} else if (*m_cp == '+') {
++m_cp;
}
if (! isdigit (*m_cp)) {
return false;
}
value = 0;
while (isdigit (*m_cp)) {
if ((value * 10) / 10 != value) {
throw tl::Exception (tl::to_string (QObject::tr ("Range overflow on long integer")));
}
value *= 10;
value += (*m_cp - '0');
++m_cp;
}
if (minus) {
value = -value;
}
return true;
} }
bool bool
tl::Extractor::try_read (long long &value) tl::Extractor::try_read (long long &value)
{ {
if (! *skip ()) { return try_read_signed_int (value);
return false;
}
bool minus = false;
if (*m_cp == '-') {
minus = true;
++m_cp;
} else if (*m_cp == '+') {
++m_cp;
}
if (! isdigit (*m_cp)) {
return false;
}
value = 0;
while (isdigit (*m_cp)) {
if ((value * 10) / 10 != value) {
throw tl::Exception (tl::to_string (QObject::tr ("Range overflow on long long integer")));
}
value *= 10;
value += (*m_cp - '0');
++m_cp;
}
if (minus) {
value = -value;
}
return true;
} }
bool bool
tl::Extractor::try_read (double &value) tl::Extractor::try_read (double &value)
{ {

View File

@ -732,6 +732,9 @@ public:
} }
private: private:
template <class T> bool try_read_signed_int (T &value);
template <class T> bool try_read_unsigned_int (T &value);
const char *m_cp; const char *m_cp;
std::string m_str; std::string m_str;
}; };

View File

@ -1268,7 +1268,7 @@ public:
*/ */
bool is_longlong () const bool is_longlong () const
{ {
return m_type == t_longlong || is_long (); return m_type == t_longlong;
} }
/** /**
@ -1276,7 +1276,7 @@ public:
*/ */
bool is_ulonglong () const bool is_ulonglong () const
{ {
return m_type == t_ulonglong || is_ulong (); return m_type == t_ulonglong;
} }
#if defined(HAVE_64BIT_COORD) #if defined(HAVE_64BIT_COORD)

View File

@ -137,7 +137,7 @@ TEST(1)
EXPECT_EQ (v.is_cstring (), false); EXPECT_EQ (v.is_cstring (), false);
EXPECT_EQ (v.is_id (), false); EXPECT_EQ (v.is_id (), false);
EXPECT_EQ (v.is_ulong (), true); EXPECT_EQ (v.is_ulong (), true);
EXPECT_EQ (v.is_ulonglong (), true); EXPECT_EQ (v.is_ulonglong (), false);
EXPECT_EQ (v.is_long (), false); EXPECT_EQ (v.is_long (), false);
EXPECT_EQ (v.is_longlong (), false); EXPECT_EQ (v.is_longlong (), false);
EXPECT_EQ (v.is_double (), false); EXPECT_EQ (v.is_double (), false);
@ -172,7 +172,7 @@ TEST(1)
EXPECT_EQ (v.is<unsigned long> (), false); EXPECT_EQ (v.is<unsigned long> (), false);
EXPECT_EQ (v.is<long> (), false); EXPECT_EQ (v.is<long> (), false);
EXPECT_EQ (v.is_ulong (), true); EXPECT_EQ (v.is_ulong (), true);
EXPECT_EQ (v.is_ulonglong (), true); EXPECT_EQ (v.is_ulonglong (), false);
EXPECT_EQ (v.is_long (), false); EXPECT_EQ (v.is_long (), false);
EXPECT_EQ (v.is_longlong (), false); EXPECT_EQ (v.is_longlong (), false);
EXPECT_EQ (v.is_id (), false); EXPECT_EQ (v.is_id (), false);
@ -202,7 +202,7 @@ TEST(1)
EXPECT_EQ (v.is_list (), false); EXPECT_EQ (v.is_list (), false);
EXPECT_EQ (v.is_cstring (), false); EXPECT_EQ (v.is_cstring (), false);
EXPECT_EQ (v.is_long (), true); EXPECT_EQ (v.is_long (), true);
EXPECT_EQ (v.is_longlong (), true); EXPECT_EQ (v.is_longlong (), false);
EXPECT_EQ (v.is_ulong (), false); EXPECT_EQ (v.is_ulong (), false);
EXPECT_EQ (v.is_ulonglong (), false); EXPECT_EQ (v.is_ulonglong (), false);
EXPECT_EQ (v.is<long> (), false); EXPECT_EQ (v.is<long> (), false);
@ -389,7 +389,7 @@ TEST(1)
EXPECT_EQ (v.is_char (), false); EXPECT_EQ (v.is_char (), false);
EXPECT_EQ (v.is_long (), true); EXPECT_EQ (v.is_long (), true);
EXPECT_EQ (v.is_ulong (), false); EXPECT_EQ (v.is_ulong (), false);
EXPECT_EQ (v.is_longlong (), true); EXPECT_EQ (v.is_longlong (), false);
EXPECT_EQ (v.is_ulonglong (), false); EXPECT_EQ (v.is_ulonglong (), false);
EXPECT_EQ (v.is_double (), false); EXPECT_EQ (v.is_double (), false);
EXPECT_EQ (v.to_parsable_string (), "#2"); EXPECT_EQ (v.to_parsable_string (), "#2");