diff options
author | Zolnai Tamás <zolnaitamas2000@gmail.com> | 2013-03-25 12:06:20 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2013-03-25 17:33:29 +0100 |
commit | bd60d41176da540b01d7583cfe00637431967f39 (patch) | |
tree | 8aae129fdb981229e3d48bea5adca1c113bae636 /sal | |
parent | Clean up new toUInt64 (diff) | |
download | core-bd60d41176da540b01d7583cfe00637431967f39.tar.gz core-bd60d41176da540b01d7583cfe00637431967f39.zip |
Handle oveflow in O(U)String::toInt() functions
Return 0 when overflow.
The base idea in unsigned case is checking wheather
(Max-nDigit)/nRadix < n
But for efficency, take out nDiv = Max/nRadix from loop
and corrigate it with -1 if needed.
In signed case use minimum value if the number is negativ.
Change-Id: I5b77580adbf12421b6c4b785ba9bc2a080accba2
Signed-off-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'sal')
-rw-r--r-- | sal/rtl/strtmpl.cxx | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/sal/rtl/strtmpl.cxx b/sal/rtl/strtmpl.cxx index 69bd5ee18649..6859af15b31e 100644 --- a/sal/rtl/strtmpl.cxx +++ b/sal/rtl/strtmpl.cxx @@ -941,11 +941,15 @@ namespace { bNeg = sal_False; } + const T nDiv = bNeg ? -(std::numeric_limits<T>::min()/nRadix) : (std::numeric_limits<T>::max()/nRadix); + const sal_Int16 nMod = bNeg ? -(std::numeric_limits<T>::min()%nRadix) : (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; n *= nRadix; n += nDigit; @@ -978,11 +982,15 @@ namespace { if ( *pStr == '+' ) ++pStr; + const T nDiv = std::numeric_limits<T>::max()/nRadix; + const 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; n *= nRadix; n += nDigit; |