You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by gs...@apache.org on 2011/04/14 15:16:03 UTC

svn commit: r1092219 - in /qpid/trunk/qpid/cpp/src: qpid/types/Variant.cpp tests/Variant.cpp

Author: gsim
Date: Thu Apr 14 13:16:03 2011
New Revision: 1092219

URL: http://svn.apache.org/viewvc?rev=1092219&view=rev
Log:
QPID-3206: added special cases to catch negative numeric string conversions to unsigned values

Modified:
    qpid/trunk/qpid/cpp/src/qpid/types/Variant.cpp
    qpid/trunk/qpid/cpp/src/tests/Variant.cpp

Modified: qpid/trunk/qpid/cpp/src/qpid/types/Variant.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/types/Variant.cpp?rev=1092219&r1=1092218&r2=1092219&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/types/Variant.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/types/Variant.cpp Thu Apr 14 13:16:03 2011
@@ -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));
     }
 };
 

Modified: qpid/trunk/qpid/cpp/src/tests/Variant.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/tests/Variant.cpp?rev=1092219&r1=1092218&r2=1092219&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/tests/Variant.cpp (original)
+++ qpid/trunk/qpid/cpp/src/tests/Variant.cpp Thu Apr 14 13:16:03 2011
@@ -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;



---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:commits-subscribe@qpid.apache.org