summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGordon Sim <gsim@apache.org>2011-04-14 13:16:03 +0000
committerGordon Sim <gsim@apache.org>2011-04-14 13:16:03 +0000
commita2cd8c6eb2674f432f03b5b4cdfc8322f85712ed (patch)
tree6208fe832de9b5f872b85cd37a7210d960811295
parent3ff288653b2a0bde0849a0a0438a2bc6b7ad00b2 (diff)
downloadqpid-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.cpp21
-rw-r--r--qpid/cpp/src/tests/Variant.cpp58
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;