diff options
author | Gordon Sim <gsim@apache.org> | 2011-04-14 13:16:03 +0000 |
---|---|---|
committer | Gordon Sim <gsim@apache.org> | 2011-04-14 13:16:03 +0000 |
commit | a2cd8c6eb2674f432f03b5b4cdfc8322f85712ed (patch) | |
tree | 6208fe832de9b5f872b85cd37a7210d960811295 | |
parent | 3ff288653b2a0bde0849a0a0438a2bc6b7ad00b2 (diff) | |
download | qpid-python-a2cd8c6eb2674f432f03b5b4cdfc8322f85712ed.tar.gz |
QPID-3206: added special cases to catch negative numeric string conversions to unsigned values
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1092219 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | qpid/cpp/src/qpid/types/Variant.cpp | 21 | ||||
-rw-r--r-- | qpid/cpp/src/tests/Variant.cpp | 58 |
2 files changed, 75 insertions, 4 deletions
diff --git a/qpid/cpp/src/qpid/types/Variant.cpp b/qpid/cpp/src/qpid/types/Variant.cpp index 9cc3cfe5fc..8d1a439631 100644 --- a/qpid/cpp/src/qpid/types/Variant.cpp +++ b/qpid/cpp/src/qpid/types/Variant.cpp @@ -111,11 +111,24 @@ class VariantImpl template<class T> T convertFromString() const { std::string* s = reinterpret_cast<std::string*>(value.v); - try { - return boost::lexical_cast<T>(*s); - } catch(const boost::bad_lexical_cast&) { - throw InvalidConversion(QPID_MSG("Cannot convert " << *s)); + if (std::numeric_limits<T>::is_signed || s->find('-') != 0) { + //lexical_cast won't fail if string is a negative number and T is unsigned + try { + return boost::lexical_cast<T>(*s); + } catch(const boost::bad_lexical_cast&) { + //don't return, throw exception below + } + } else { + //T is unsigned and number starts with '-' + try { + //handle special case of negative zero + if (boost::lexical_cast<int>(*s) == 0) return 0; + //else its a non-zero negative number so throw exception at end of function + } catch(const boost::bad_lexical_cast&) { + //wasn't a valid int, therefore not a valid uint + } } + throw InvalidConversion(QPID_MSG("Cannot convert " << *s)); } }; diff --git a/qpid/cpp/src/tests/Variant.cpp b/qpid/cpp/src/tests/Variant.cpp index b4188f524b..fb00149628 100644 --- a/qpid/cpp/src/tests/Variant.cpp +++ b/qpid/cpp/src/tests/Variant.cpp @@ -86,6 +86,64 @@ QPID_AUTO_TEST_CASE(testConversions) BOOST_CHECK_THROW(value.asBool(), InvalidConversion); } +QPID_AUTO_TEST_CASE(testConversionsFromString) +{ + Variant value; + value = "5"; + BOOST_CHECK_EQUAL(5, value.asInt16()); + BOOST_CHECK_EQUAL(5u, value.asUint16()); + + value = "-5"; + BOOST_CHECK_EQUAL(-5, value.asInt16()); + BOOST_CHECK_THROW(value.asUint16(), InvalidConversion); + + value = "18446744073709551615"; + BOOST_CHECK_EQUAL(18446744073709551615ull, value.asUint64()); + BOOST_CHECK_THROW(value.asInt64(), InvalidConversion); + + value = "9223372036854775808"; + BOOST_CHECK_EQUAL(9223372036854775808ull, value.asUint64()); + BOOST_CHECK_THROW(value.asInt64(), InvalidConversion); + + value = "-9223372036854775809"; + BOOST_CHECK_THROW(value.asUint64(), InvalidConversion); + BOOST_CHECK_THROW(value.asInt64(), InvalidConversion); + + value = "2147483648"; + BOOST_CHECK_EQUAL(2147483648ul, value.asUint32()); + BOOST_CHECK_THROW(value.asInt32(), InvalidConversion); + + value = "-2147483649"; + BOOST_CHECK_THROW(value.asUint32(), InvalidConversion); + BOOST_CHECK_THROW(value.asInt32(), InvalidConversion); + + value = "32768"; + BOOST_CHECK_EQUAL(32768u, value.asUint16()); + BOOST_CHECK_THROW(value.asInt16(), InvalidConversion); + + value = "-32769"; + BOOST_CHECK_THROW(value.asUint16(), InvalidConversion); + BOOST_CHECK_THROW(value.asInt16(), InvalidConversion); + + value = "-2.5"; + BOOST_CHECK_EQUAL(-2.5, value.asFloat()); + + value = "-0.875432e10"; + BOOST_CHECK_EQUAL(-0.875432e10, value.asDouble()); + + value = "-0"; + BOOST_CHECK_EQUAL(0, value.asInt16()); + BOOST_CHECK_EQUAL(0u, value.asUint16()); + + value = "-000"; + BOOST_CHECK_EQUAL(0, value.asInt16()); + BOOST_CHECK_EQUAL(0u, value.asUint16()); + + value = "-0010"; + BOOST_CHECK_EQUAL(0, value.asInt16()); + BOOST_CHECK_EQUAL(0u, value.asUint16()); +} + QPID_AUTO_TEST_CASE(testSizeConversionsUint) { Variant value; |