summaryrefslogtreecommitdiff
path: root/sal/rtl
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2013-06-12 15:58:17 +0200
committerStephan Bergmann <sbergman@redhat.com>2013-06-13 17:08:36 +0200
commit3af0114a295d2a6c600117adb5bcd6689c0c787e (patch)
tree262f32143b99a8754e517be454681267cadaa85f /sal/rtl
parent4edbfa892bfe6ca81c88363b2249e0b7d5eef31f (diff)
Introduce O[U]String::toUInt32
...which has become necessary since bd60d41176da540b01d7583cfe00637431967f39 "Handle oveflow in O(U)String::toInt() functions" reduces values in the range (SAL_MAX_INT32 .. SAL_MAX_UINT32] to zero, but some calls of toInt32(16) relied on getting a correct (unsigned) value for the whole input range ["0" .. "FFFFFFFF"] (see libreoffice-4-1 commit 9bf6c83367cedb7be81bf67f30d2147d26c7a8c3 "Revert overflow checks in O[U]String::toInt{32,64} again"). Audited all uses of toInt32/64 with non-decimal radix. (There is still a TODO comment in oox/source/helper/attributelist.cxx, and stoc/source/typeconv/convert.cxx will still need some love and test code.) Change-Id: Iadaca1c0e41dab553687d0ce41c20c10cd657a95
Diffstat (limited to 'sal/rtl')
-rw-r--r--sal/rtl/strtmpl.cxx69
1 files changed, 42 insertions, 27 deletions
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);
}
/* ======================================================================= */