summaryrefslogtreecommitdiff
path: root/unotools
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2017-12-22 21:20:58 +0000
committerCaolán McNamara <caolanm@redhat.com>2017-12-23 17:22:46 +0100
commit87114b364cdee276b81c21af2538c5612a1ce5d2 (patch)
tree475e88cfd7cb288011c7ed4c383e88ec08cec16c /unotools
parent40cfea9a5b4854ada381642d502bf8f74c87c00b (diff)
ofz#4722 Integer-overflow
Change-Id: I772ff6e6758610e7fa746f5e9b308accdea8159e Reviewed-on: https://gerrit.libreoffice.org/46997 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'unotools')
-rw-r--r--unotools/source/misc/datetime.cxx65
1 files changed, 39 insertions, 26 deletions
diff --git a/unotools/source/misc/datetime.cxx b/unotools/source/misc/datetime.cxx
index b0c1afce82eb..789e1ad8143a 100644
--- a/unotools/source/misc/datetime.cxx
+++ b/unotools/source/misc/datetime.cxx
@@ -27,15 +27,8 @@
namespace
{
- /** convert string to number with optional min and max values */
- template <typename T>
- bool convertNumber( T& rValue,
- const OUString& rString,
- T /*nMin*/ = -1, T /*nMax*/ = -1)
+ bool checkAllNumber(const OUString& rString)
{
- bool bNeg = false;
- rValue = 0;
-
sal_Int32 nPos = 0;
sal_Int32 nLen = rString.getLength();
@@ -44,28 +37,48 @@ namespace
nPos++;
if( nPos < nLen && '-' == rString[nPos] )
- {
- bNeg = true;
nPos++;
- }
// get number
while( nPos < nLen &&
'0' <= rString[nPos] &&
'9' >= rString[nPos] )
{
- // TODO: check overflow!
- rValue *= 10;
- rValue += (rString[nPos] - u'0');
nPos++;
}
- if( bNeg )
- rValue *= -1;
-
return nPos == nLen;
}
+ /** convert string to number with optional min and max values */
+ bool convertNumber32(sal_Int32& rValue,
+ const OUString& rString,
+ sal_Int32 /*nMin*/ = -1, sal_Int32 /*nMax*/ = -1)
+ {
+ if (!checkAllNumber(rString))
+ {
+ rValue = 0;
+ return false;
+ }
+
+ rValue = rString.toInt32();
+ return true;
+ }
+
+ bool convertNumber64(sal_Int64& rValue,
+ const OUString& rString,
+ sal_Int64 /*nMin*/ = -1, sal_Int64 /*nMax*/ = -1)
+ {
+ if (!checkAllNumber(rString))
+ {
+ rValue = 0;
+ return false;
+ }
+
+ rValue = rString.toInt64();
+ return true;
+ }
+
// although the standard calls for fixed-length (zero-padded) tokens
// (in their integer part), we are here liberal and allow shorter tokens
// (when there are separators, else it is ambiguous).
@@ -319,13 +332,13 @@ bool ISO8601parseDate(const OUString &aDateStr, css::util::Date& rDate)
else
{
sal_Int32 n = 0;
- if ( !convertNumber<sal_Int32>( nYear, aDateStr.getToken( 0, '-', n ), 0, 9999 ) )
+ if ( !convertNumber32( nYear, aDateStr.getToken( 0, '-', n ), 0, 9999 ) )
bSuccess = false;
if ( nDateTokens >= 2 )
- if ( !convertNumber<sal_Int32>( nMonth, aDateStr.getToken( 0, '-', n ), 0, 12 ) )
+ if ( !convertNumber32( nMonth, aDateStr.getToken( 0, '-', n ), 0, 12 ) )
bSuccess = false;
if ( nDateTokens >= 3 )
- if ( !convertNumber<sal_Int32>( nDay, aDateStr.getToken( 0, '-', n ), 0, 31 ) )
+ if ( !convertNumber32( nDay, aDateStr.getToken( 0, '-', n ), 0, 31 ) )
bSuccess = false;
}
@@ -359,12 +372,12 @@ bool ISO8601parseTime(const OUString &aTimeStr, css::util::Time& rTime)
if ( bFrac && n < aTimeStr.getLength())
// is it junk or the timezone?
bSuccess = getISO8601TimeZoneToken(aTimeStr, n, tokTz);
- if (bSuccess && (bSuccess = convertNumber<sal_Int32>( nHour, tokInt, 0, 23 )) )
+ if (bSuccess && (bSuccess = convertNumber32( nHour, tokInt, 0, 23 )) )
{
if (bFrac)
{
sal_Int64 fracNumerator;
- if ( (bSuccess = convertNumber(fracNumerator, tokFrac)) )
+ if ( (bSuccess = convertNumber64(fracNumerator, tokFrac)) )
{
double frac = static_cast<double>(fracNumerator) / pow(static_cast<double>(10), static_cast<double>(tokFrac.getLength()));
// minutes
@@ -395,12 +408,12 @@ bool ISO8601parseTime(const OUString &aTimeStr, css::util::Time& rTime)
if ( bFrac && n < aTimeStr.getLength())
// is it junk or the timezone?
bSuccess = getISO8601TimeZoneToken(aTimeStr, n, tokTz);
- if (bSuccess && (bSuccess = convertNumber<sal_Int32>( nMin, tokInt, 0, 59 )) )
+ if (bSuccess && (bSuccess = convertNumber32( nMin, tokInt, 0, 59 )) )
{
if (bFrac)
{
sal_Int64 fracNumerator;
- if ( (bSuccess = convertNumber(fracNumerator, tokFrac)) )
+ if ( (bSuccess = convertNumber64(fracNumerator, tokFrac)) )
{
double frac = static_cast<double>(fracNumerator) / pow(static_cast<double>(10), static_cast<double>(tokFrac.getLength()));
// seconds
@@ -426,12 +439,12 @@ bool ISO8601parseTime(const OUString &aTimeStr, css::util::Time& rTime)
// is it junk or the timezone?
bSuccess = getISO8601TimeZoneToken(aTimeStr, n, tokTz);
// max 60 for leap seconds
- if (bSuccess && (bSuccess = convertNumber<sal_Int32>( nSec, tokInt, 0, 60 )) )
+ if (bSuccess && (bSuccess = convertNumber32( nSec, tokInt, 0, 60 )) )
{
if (bFrac)
{
sal_Int64 fracNumerator;
- if ( (bSuccess = convertNumber(fracNumerator, tokFrac)) )
+ if ( (bSuccess = convertNumber64(fracNumerator, tokFrac)) )
{
double frac = static_cast<double>(fracNumerator) / pow(static_cast<double>(10), static_cast<double>(tokFrac.getLength()));
// nanoseconds