[Libreoffice-commits] core.git: 3 commits - sal/CppunitTest_sal_rtl_strings.mk sal/inc sal/qa sal/rtl sal/util
Stephan Bergmann
sbergman at redhat.com
Mon Mar 25 09:33:53 PDT 2013
sal/CppunitTest_sal_rtl_strings.mk | 1
sal/inc/rtl/string.h | 21 +++++++++
sal/inc/rtl/string.hxx | 23 +++++++++-
sal/inc/rtl/ustring.h | 14 +++---
sal/inc/rtl/ustring.hxx | 11 +++--
sal/qa/rtl/strings/test_strings_toint.cxx | 65 ++++++++++++++++++++++++++++++
sal/rtl/strtmpl.cxx | 8 +++
sal/util/sal.map | 1
8 files changed, 133 insertions(+), 11 deletions(-)
New commits:
commit 40dcf2d713e67ef4d8c68a6df98954f1f0b783db
Author: Stephan Bergmann <sbergman at redhat.com>
Date: Mon Mar 25 16:24:48 2013 +0100
Add test case for toInt overflow detection
Change-Id: I1c5b66888baac8aa1bc99c06579e0ef3638a4877
diff --git a/sal/CppunitTest_sal_rtl_strings.mk b/sal/CppunitTest_sal_rtl_strings.mk
index 222cedf..1d56ecd 100644
--- a/sal/CppunitTest_sal_rtl_strings.mk
+++ b/sal/CppunitTest_sal_rtl_strings.mk
@@ -38,6 +38,7 @@ $(eval $(call gb_CppunitTest_add_exception_objects,sal_rtl_strings,\
sal/qa/rtl/strings/test_oustring_noadditional \
sal/qa/rtl/strings/test_oustring_startswith \
sal/qa/rtl/strings/test_oustring_stringliterals \
+ sal/qa/rtl/strings/test_strings_toint \
sal/qa/rtl/strings/test_strings_valuex \
))
diff --git a/sal/inc/rtl/string.hxx b/sal/inc/rtl/string.hxx
index 01ee464..f6cec59 100644
--- a/sal/inc/rtl/string.hxx
+++ b/sal/inc/rtl/string.hxx
@@ -1349,7 +1349,8 @@ public:
@param radix the radix (between 2 and 36)
@return the int32 represented from this string.
- 0 if this string represents no number.
+ 0 if this string represents no number or one of too large
+ magnitude.
*/
sal_Int32 toInt32( sal_Int16 radix = 10 ) const SAL_THROW(())
{
@@ -1363,7 +1364,8 @@ public:
@param radix the radix (between 2 and 36)
@return the int64 represented from this string.
- 0 if this string represents no number.
+ 0 if this string represents no number or one of too large
+ magnitude.
*/
sal_Int64 toInt64( sal_Int16 radix = 10 ) const SAL_THROW(())
{
@@ -1377,7 +1379,8 @@ public:
@param radix the radix (between 2 and 36)
@return the uint64 represented from this string.
- 0 if this string represents no number.
+ 0 if this string represents no number or one of too large
+ magnitude.
@since LibreOffice 4.1
*/
diff --git a/sal/inc/rtl/ustring.hxx b/sal/inc/rtl/ustring.hxx
index 2afd95c..768f552 100644
--- a/sal/inc/rtl/ustring.hxx
+++ b/sal/inc/rtl/ustring.hxx
@@ -1828,7 +1828,8 @@ public:
@param radix the radix (between 2 and 36)
@return the int32 represented from this string.
- 0 if this string represents no number.
+ 0 if this string represents no number or one of too large
+ magnitude.
*/
sal_Int32 toInt32( sal_Int16 radix = 10 ) const SAL_THROW(())
{
@@ -1842,7 +1843,8 @@ public:
@param radix the radix (between 2 and 36)
@return the int64 represented from this string.
- 0 if this string represents no number.
+ 0 if this string represents no number or one of too large
+ magnitude.
*/
sal_Int64 toInt64( sal_Int16 radix = 10 ) const SAL_THROW(())
{
@@ -1856,7 +1858,8 @@ public:
@param radix the radix (between 2 and 36)
@return the uint64 represented from this string.
- 0 if this string represents no number.
+ 0 if this string represents no number or one of too large
+ magnitude.
@since LibreOffice 4.1
*/
diff --git a/sal/qa/rtl/strings/test_strings_toint.cxx b/sal/qa/rtl/strings/test_strings_toint.cxx
new file mode 100644
index 0000000..4a4f549
--- /dev/null
+++ b/sal/qa/rtl/strings/test_strings_toint.cxx
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "sal/config.h"
+
+#include "cppunit/TestAssert.h"
+#include "cppunit/TestFixture.h"
+#include "cppunit/extensions/HelperMacros.h"
+#include "rtl/string.hxx"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+namespace {
+
+template< typename T > class Test: public CppUnit::TestFixture {
+private:
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(testToInt32Overflow);
+ CPPUNIT_TEST(testToInt64Overflow);
+ CPPUNIT_TEST(testToUInt64Overflow);
+ CPPUNIT_TEST_SUITE_END();
+
+ 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 + 1, T("-2147483647").toInt32());
+ CPPUNIT_ASSERT_EQUAL(SAL_MAX_INT32 - 1, T("2147483646").toInt32());
+ CPPUNIT_ASSERT_EQUAL(SAL_MAX_INT32, T("2147483647").toInt32());
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(0), T("2147483648").toInt32());
+ }
+
+ void testToInt64Overflow() {
+ CPPUNIT_ASSERT_EQUAL(sal_Int64(0), T("-9223372036854775809").toInt64());
+ CPPUNIT_ASSERT_EQUAL(
+ SAL_MIN_INT64, T("-9223372036854775808").toInt64());
+ CPPUNIT_ASSERT_EQUAL(
+ SAL_MIN_INT64 + 1, T("-9223372036854775807").toInt64());
+ CPPUNIT_ASSERT_EQUAL(
+ SAL_MAX_INT64 - 1, T("9223372036854775806").toInt64());
+ CPPUNIT_ASSERT_EQUAL(SAL_MAX_INT64, T("9223372036854775807").toInt64());
+ CPPUNIT_ASSERT_EQUAL(sal_Int64(0), T("9223372036854775808").toInt64());
+ }
+
+ void testToUInt64Overflow() {
+ CPPUNIT_ASSERT_EQUAL(
+ SAL_MAX_UINT64 - 1, T("18446744073709551614").toUInt64());
+ CPPUNIT_ASSERT_EQUAL(
+ SAL_MAX_UINT64, T("18446744073709551615").toUInt64());
+ CPPUNIT_ASSERT_EQUAL(
+ sal_uInt64(0), T("18446744073709551616").toUInt64());
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test< rtl::OString >);
+CPPUNIT_TEST_SUITE_REGISTRATION(Test< rtl::OUString >);
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit bd60d41176da540b01d7583cfe00637431967f39
Author: Zolnai Tamás <zolnaitamas2000 at gmail.com>
Date: Mon Mar 25 12:06:20 2013 +0100
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 at redhat.com>
diff --git a/sal/rtl/strtmpl.cxx b/sal/rtl/strtmpl.cxx
index 69bd5ee..6859af1 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;
commit 476081b19bd71d5c1eb7d82eee4821f099ecde78
Author: Stephan Bergmann <sbergman at redhat.com>
Date: Mon Mar 25 16:20:31 2013 +0100
Clean up new toUInt64
Change-Id: Ic908cb5cc9169ab1baae2c1c52070adfb9afba39
diff --git a/sal/inc/rtl/string.h b/sal/inc/rtl/string.h
index a16d61e..93cffa1 100644
--- a/sal/inc/rtl/string.h
+++ b/sal/inc/rtl/string.h
@@ -762,6 +762,27 @@ SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_str_toInt32(
SAL_DLLPUBLIC sal_Int64 SAL_CALL rtl_str_toInt64(
const sal_Char * str, sal_Int16 radix ) SAL_THROW_EXTERN_C();
+/** Interpret a string as an unsigned long integer.
+
+ This function cannot be used for language-specific conversion. The string
+ must be null-terminated.
+
+ @param str
+ a null-terminated string.
+
+ @param radix
+ the radix. Must be between RTL_USTR_MIN_RADIX (2) and RTL_USTR_MAX_RADIX
+ (36), inclusive.
+
+ @return
+ the unsigned long integer value represented by the string, or 0 if the
+ string does not represent an unsigned long integer.
+
+ @since LibreOffice 4.1
+ */
+SAL_DLLPUBLIC sal_uInt64 SAL_CALL rtl_str_toUInt64(
+ const sal_Char * str, sal_Int16 radix ) SAL_THROW_EXTERN_C();
+
/** Interpret a string as a float.
This function cannot be used for language-specific conversion. The string
diff --git a/sal/inc/rtl/string.hxx b/sal/inc/rtl/string.hxx
index cbb8cd5..01ee464 100644
--- a/sal/inc/rtl/string.hxx
+++ b/sal/inc/rtl/string.hxx
@@ -1371,6 +1371,22 @@ public:
}
/**
+ Returns the uint64 value from this string.
+
+ This function can't be used for language specific conversion.
+
+ @param radix the radix (between 2 and 36)
+ @return the uint64 represented from this string.
+ 0 if this string represents no number.
+
+ @since LibreOffice 4.1
+ */
+ sal_uInt64 toUInt64( sal_Int16 radix = 10 ) const SAL_THROW(())
+ {
+ return rtl_str_toUInt64( pData->buffer, radix );
+ }
+
+ /**
Returns the float value from this string.
This function can't be used for language specific conversion.
diff --git a/sal/inc/rtl/ustring.h b/sal/inc/rtl/ustring.h
index f6bf956..da6720b 100644
--- a/sal/inc/rtl/ustring.h
+++ b/sal/inc/rtl/ustring.h
@@ -1073,7 +1073,7 @@ SAL_DLLPUBLIC sal_Bool SAL_CALL rtl_ustr_toBoolean(
SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_toInt32(
const sal_Unicode * str, sal_Int16 radix ) SAL_THROW_EXTERN_C();
-/** Interpret a string as an unsigned long integer.
+/** Interpret a string as a long integer.
This function cannot be used for language-specific conversion. The string
must be null-terminated.
@@ -1089,10 +1089,10 @@ SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_ustr_toInt32(
the long integer value represented by the string, or 0 if the string does
not represent a long integer.
*/
-SAL_DLLPUBLIC sal_uInt64 SAL_CALL rtl_ustr_toUInt64(
+SAL_DLLPUBLIC sal_Int64 SAL_CALL rtl_ustr_toInt64(
const sal_Unicode * str, sal_Int16 radix ) SAL_THROW_EXTERN_C();
-/** Interpret a string as a long integer.
+/** Interpret a string as an unsigned long integer.
This function cannot be used for language-specific conversion. The string
must be null-terminated.
@@ -1105,10 +1105,12 @@ SAL_DLLPUBLIC sal_uInt64 SAL_CALL rtl_ustr_toUInt64(
(36), inclusive.
@return
- the long integer value represented by the string, or 0 if the string does
- not represent a long integer.
+ the unsigned long integer value represented by the string, or 0 if the
+ string does not represent an unsigned long integer.
+
+ @since LibreOffice 4.1
*/
-SAL_DLLPUBLIC sal_Int64 SAL_CALL rtl_ustr_toInt64(
+SAL_DLLPUBLIC sal_uInt64 SAL_CALL rtl_ustr_toUInt64(
const sal_Unicode * str, sal_Int16 radix ) SAL_THROW_EXTERN_C();
/** Interpret a string as a float.
diff --git a/sal/inc/rtl/ustring.hxx b/sal/inc/rtl/ustring.hxx
index 4d9650e..2afd95c 100644
--- a/sal/inc/rtl/ustring.hxx
+++ b/sal/inc/rtl/ustring.hxx
@@ -1857,6 +1857,8 @@ public:
@param radix the radix (between 2 and 36)
@return the uint64 represented from this string.
0 if this string represents no number.
+
+ @since LibreOffice 4.1
*/
sal_uInt64 toUInt64( sal_Int16 radix = 10 ) const SAL_THROW(())
{
diff --git a/sal/util/sal.map b/sal/util/sal.map
index e21ff0a..f2790d5 100644
--- a/sal/util/sal.map
+++ b/sal/util/sal.map
@@ -658,6 +658,7 @@ LIBO_UDK_4.1 { # symbols available in >= LibO 4.1
rtl_uString_ensureCapacity;
rtl_string_alloc;
rtl_uString_alloc;
+ rtl_str_toUInt64;
rtl_str_valueOfUInt64;
rtl_ustr_valueOfUInt64;
rtl_ustr_toUInt64;
More information about the Libreoffice-commits
mailing list