summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZolnai Tamás <zolnaitamas2000@gmail.com>2013-03-25 12:06:20 +0100
committerStephan Bergmann <sbergman@redhat.com>2013-03-25 17:33:29 +0100
commitbd60d41176da540b01d7583cfe00637431967f39 (patch)
tree8aae129fdb981229e3d48bea5adca1c113bae636
parent476081b19bd71d5c1eb7d82eee4821f099ecde78 (diff)
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>
-rw-r--r--sal/rtl/strtmpl.cxx8
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;