Kaydet (Commit) 9bf6c833 authored tarafından Stephan Bergmann's avatar Stephan Bergmann

Revert overflow checks in O[U]String::toInt{32,64} again

...originally introduced with bd60d411 "Handle
oveflow in O(U)String::toInt() functions."  As pointed out by Noel Power, there
is existing code using toInt32(16) to read an effectively unsigned hex string
into a sal_Int32, which used to work fine with the wrap-around overflow but now
fails when toInt32 explicitly returns 0 for large values.  See, e.g., use of
oox::AttributeList::getIntegerHex (indirectly calling OUString::toInt32) in
ColorScaleRule::importColor (sc/source/filter/oox/condformatbuffer.cxx).

To prevent any regressions in LO 4.1, remove the explicit checks from
toInt{32,64} again for now.  (They were "merely" added as a general safety
measure, not to address some specific problem, IIRC.)  On master, the approach
will rather be to introduce toUInt32 and adapt client code as necessary.

Change-Id: Id332cff18a99b8bd2dcccd7988b7aad3a9e98c4c
üst 7a62dba0
...@@ -1336,8 +1336,7 @@ public: ...@@ -1336,8 +1336,7 @@ public:
@param radix the radix (between 2 and 36) @param radix the radix (between 2 and 36)
@return the int32 represented from this string. @return the int32 represented from this string.
0 if this string represents no number or one of too large 0 if this string represents no number.
magnitude.
*/ */
sal_Int32 toInt32( sal_Int16 radix = 10 ) const SAL_THROW(()) sal_Int32 toInt32( sal_Int16 radix = 10 ) const SAL_THROW(())
{ {
...@@ -1351,8 +1350,7 @@ public: ...@@ -1351,8 +1350,7 @@ public:
@param radix the radix (between 2 and 36) @param radix the radix (between 2 and 36)
@return the int64 represented from this string. @return the int64 represented from this string.
0 if this string represents no number or one of too large 0 if this string represents no number.
magnitude.
*/ */
sal_Int64 toInt64( sal_Int16 radix = 10 ) const SAL_THROW(()) sal_Int64 toInt64( sal_Int16 radix = 10 ) const SAL_THROW(())
{ {
......
...@@ -1799,8 +1799,7 @@ public: ...@@ -1799,8 +1799,7 @@ public:
@param radix the radix (between 2 and 36) @param radix the radix (between 2 and 36)
@return the int32 represented from this string. @return the int32 represented from this string.
0 if this string represents no number or one of too large 0 if this string represents no number.
magnitude.
*/ */
sal_Int32 toInt32( sal_Int16 radix = 10 ) const SAL_THROW(()) sal_Int32 toInt32( sal_Int16 radix = 10 ) const SAL_THROW(())
{ {
...@@ -1814,8 +1813,7 @@ public: ...@@ -1814,8 +1813,7 @@ public:
@param radix the radix (between 2 and 36) @param radix the radix (between 2 and 36)
@return the int64 represented from this string. @return the int64 represented from this string.
0 if this string represents no number or one of too large 0 if this string represents no number.
magnitude.
*/ */
sal_Int64 toInt64( sal_Int16 radix = 10 ) const SAL_THROW(()) sal_Int64 toInt64( sal_Int16 radix = 10 ) const SAL_THROW(())
{ {
......
...@@ -27,16 +27,13 @@ private: ...@@ -27,16 +27,13 @@ private:
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
void testToInt32Overflow() { void testToInt32Overflow() {
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), T("-2147483649").toInt32());
CPPUNIT_ASSERT_EQUAL(SAL_MIN_INT32, T("-2147483648").toInt32()); CPPUNIT_ASSERT_EQUAL(SAL_MIN_INT32, T("-2147483648").toInt32());
CPPUNIT_ASSERT_EQUAL(SAL_MIN_INT32 + 1, T("-2147483647").toInt32()); CPPUNIT_ASSERT_EQUAL(SAL_MIN_INT32 + 1, T("-2147483647").toInt32());
CPPUNIT_ASSERT_EQUAL(SAL_MAX_INT32 - 1, T("2147483646").toInt32()); CPPUNIT_ASSERT_EQUAL(SAL_MAX_INT32 - 1, T("2147483646").toInt32());
CPPUNIT_ASSERT_EQUAL(SAL_MAX_INT32, T("2147483647").toInt32()); CPPUNIT_ASSERT_EQUAL(SAL_MAX_INT32, T("2147483647").toInt32());
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), T("2147483648").toInt32());
} }
void testToInt64Overflow() { void testToInt64Overflow() {
CPPUNIT_ASSERT_EQUAL(sal_Int64(0), T("-9223372036854775809").toInt64());
CPPUNIT_ASSERT_EQUAL( CPPUNIT_ASSERT_EQUAL(
SAL_MIN_INT64, T("-9223372036854775808").toInt64()); SAL_MIN_INT64, T("-9223372036854775808").toInt64());
CPPUNIT_ASSERT_EQUAL( CPPUNIT_ASSERT_EQUAL(
...@@ -44,7 +41,6 @@ private: ...@@ -44,7 +41,6 @@ private:
CPPUNIT_ASSERT_EQUAL( CPPUNIT_ASSERT_EQUAL(
SAL_MAX_INT64 - 1, T("9223372036854775806").toInt64()); SAL_MAX_INT64 - 1, T("9223372036854775806").toInt64());
CPPUNIT_ASSERT_EQUAL(SAL_MAX_INT64, T("9223372036854775807").toInt64()); CPPUNIT_ASSERT_EQUAL(SAL_MAX_INT64, T("9223372036854775807").toInt64());
CPPUNIT_ASSERT_EQUAL(sal_Int64(0), T("9223372036854775808").toInt64());
} }
void testToUInt64Overflow() { void testToUInt64Overflow() {
......
...@@ -941,35 +941,11 @@ namespace { ...@@ -941,35 +941,11 @@ namespace {
bNeg = sal_False; bNeg = sal_False;
} }
T nDiv;
sal_Int16 nMod;
if ( bNeg )
{
nDiv = std::numeric_limits<T>::min() / nRadix;
nMod = std::numeric_limits<T>::min() % nRadix;
// Cater for C++03 implementations that round the quotient down
// instead of truncating towards zero as mandated by C++11:
if ( nMod > 0 )
{
--nDiv;
nMod -= nRadix;
}
nDiv = -nDiv;
nMod = -nMod;
}
else
{
nDiv = std::numeric_limits<T>::max() / nRadix;
nMod = std::numeric_limits<T>::max() % nRadix;
}
while ( *pStr ) while ( *pStr )
{ {
nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix ); nDigit = rtl_ImplGetDigit( IMPL_RTL_USTRCODE( *pStr ), nRadix );
if ( nDigit < 0 ) if ( nDigit < 0 )
break; break;
if( ( nMod < nDigit ? nDiv-1 : nDiv ) < n )
return 0;
n *= nRadix; n *= nRadix;
n += nDigit; n += nDigit;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment