diff options
Diffstat (limited to 'sal')
-rw-r--r-- | sal/qa/rtl/strings/test_strings_toint.cxx | 7 | ||||
-rw-r--r-- | sal/rtl/strtmpl.cxx | 69 | ||||
-rw-r--r-- | sal/util/sal.map | 6 |
3 files changed, 55 insertions, 27 deletions
diff --git a/sal/qa/rtl/strings/test_strings_toint.cxx b/sal/qa/rtl/strings/test_strings_toint.cxx index 4a4f549e4495..cf5de4a3b2bf 100644 --- a/sal/qa/rtl/strings/test_strings_toint.cxx +++ b/sal/qa/rtl/strings/test_strings_toint.cxx @@ -22,6 +22,7 @@ template< typename T > class Test: public CppUnit::TestFixture { private: CPPUNIT_TEST_SUITE(Test); CPPUNIT_TEST(testToInt32Overflow); + CPPUNIT_TEST(testToUInt32Overflow); CPPUNIT_TEST(testToInt64Overflow); CPPUNIT_TEST(testToUInt64Overflow); CPPUNIT_TEST_SUITE_END(); @@ -35,6 +36,12 @@ private: CPPUNIT_ASSERT_EQUAL(sal_Int32(0), T("2147483648").toInt32()); } + void testToUInt32Overflow() { + CPPUNIT_ASSERT_EQUAL(SAL_MAX_UINT32 - 1, T("4294967294").toUInt32()); + CPPUNIT_ASSERT_EQUAL(SAL_MAX_UINT32, T("4294967295").toUInt32()); + CPPUNIT_ASSERT_EQUAL(sal_uInt32(0), T("4294967296").toUInt32()); + } + void testToInt64Overflow() { CPPUNIT_ASSERT_EQUAL(sal_Int64(0), T("-9223372036854775809").toInt64()); CPPUNIT_ASSERT_EQUAL( diff --git a/sal/rtl/strtmpl.cxx b/sal/rtl/strtmpl.cxx index 78aa1f57b863..dc54945ab6a9 100644 --- a/sal/rtl/strtmpl.cxx +++ b/sal/rtl/strtmpl.cxx @@ -999,42 +999,57 @@ sal_Int64 SAL_CALL IMPL_RTL_STRNAME( toInt64 )( const IMPL_RTL_STRCODE* pStr, } /* ----------------------------------------------------------------------- */ +namespace { + template <typename T> static inline T IMPL_RTL_STRNAME( toUInt )( const IMPL_RTL_STRCODE* pStr, + sal_Int16 nRadix ) + { + BOOST_STATIC_ASSERT(!std::numeric_limits<T>::is_signed); + sal_Int16 nDigit; + T n = 0; -sal_uInt64 SAL_CALL IMPL_RTL_STRNAME( toUInt64 )( const IMPL_RTL_STRCODE* pStr, - sal_Int16 nRadix ) - SAL_THROW_EXTERN_C() -{ - sal_Int16 nDigit; - sal_uInt64 n = 0; + if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) + nRadix = 10; - if ( (nRadix < RTL_STR_MIN_RADIX) || (nRadix > RTL_STR_MAX_RADIX) ) - nRadix = 10; + /* Skip whitespaces */ + while ( *pStr && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) ) + ++pStr; - /* Skip whitespaces */ - while ( *pStr && rtl_ImplIsWhitespace( IMPL_RTL_USTRCODE( *pStr ) ) ) - ++pStr; + // skip optional explicit sign + if ( *pStr == '+' ) + ++pStr; - // skip optional explicit sign - if ( *pStr == '+' ) - ++pStr; + T nDiv = std::numeric_limits<T>::max() / nRadix; + sal_Int16 nMod = std::numeric_limits<T>::max() % nRadix; + while ( *pStr ) + { + nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix ); + if ( nDigit < 0 ) + break; + if( ( nMod < nDigit ? nDiv-1 : nDiv ) < n ) + return 0; - const sal_uInt64 nDiv = SAL_MAX_UINT64/nRadix; - const sal_Int16 nMod = SAL_MAX_UINT64%nRadix; - while ( *pStr ) - { - nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix ); - if ( nDigit < 0 ) - break; - if( ( nMod < nDigit ? nDiv-1 : nDiv ) < n ) - return 0; + n *= nRadix; + n += nDigit; - n *= nRadix; - n += nDigit; + ++pStr; + } - ++pStr; + return n; } +} - return n; +sal_uInt32 SAL_CALL IMPL_RTL_STRNAME( toUInt32 )( const IMPL_RTL_STRCODE* pStr, + sal_Int16 nRadix ) + SAL_THROW_EXTERN_C() +{ + return IMPL_RTL_STRNAME( toUInt )<sal_uInt32>(pStr, nRadix); +} + +sal_uInt64 SAL_CALL IMPL_RTL_STRNAME( toUInt64 )( const IMPL_RTL_STRCODE* pStr, + sal_Int16 nRadix ) + SAL_THROW_EXTERN_C() +{ + return IMPL_RTL_STRNAME( toUInt )<sal_uInt64>(pStr, nRadix); } /* ======================================================================= */ diff --git a/sal/util/sal.map b/sal/util/sal.map index f2790d506a2e..1456d6db1cf8 100644 --- a/sal/util/sal.map +++ b/sal/util/sal.map @@ -664,6 +664,12 @@ LIBO_UDK_4.1 { # symbols available in >= LibO 4.1 rtl_ustr_toUInt64; } LIBO_UDK_4.0; +LIBO_UDK_4.2 { # symbols available in >= LibO 4.2 + global: + rtl_str_toUInt32; + rtl_ustr_toUInt32; +} LIBO_UDK_4.1; + PRIVATE_1.0 { global: osl_detail_ObjectRegistry_storeAddresses; |