From 595ba03fd4769c069bbe0431ab878956ef1c37ad Mon Sep 17 00:00:00 2001 From: Michael Meeks Date: Tue, 2 Oct 2012 18:39:30 +0100 Subject: update string copy semantics to be undefined in a non-crashing way. Change-Id: I03bb4db5931932280e368012cbaee6bef2854dd6 --- sal/inc/rtl/string.h | 17 +++++++++++++++++ sal/inc/rtl/string.hxx | 36 ++++++++++++------------------------ sal/inc/rtl/ustring.h | 17 +++++++++++++++++ sal/inc/rtl/ustring.hxx | 36 ++++++++++++------------------------ sal/rtl/source/strtmpl.cxx | 23 +++++++++++++++++++++++ sal/util/sal.map | 6 ++++++ 6 files changed, 87 insertions(+), 48 deletions(-) diff --git a/sal/inc/rtl/string.h b/sal/inc/rtl/string.h index c38e106e6fdb..6dd42363b98a 100644 --- a/sal/inc/rtl/string.h +++ b/sal/inc/rtl/string.h @@ -889,6 +889,23 @@ SAL_DLLPUBLIC void SAL_CALL rtl_string_newFromStr( rtl_String ** newStr, const s */ SAL_DLLPUBLIC void SAL_CALL rtl_string_newFromStr_WithLength( rtl_String ** newStr, const sal_Char * value, sal_Int32 len ) SAL_THROW_EXTERN_C(); +/** Allocate a new string that is a substring of this string. + + The substring begins at the specified beginIndex and contains count + characters. Meaningless combinations such as negative beginIndex, + or beginIndex + count greater than the length of the string have + undefined behaviour. + + @param beginIndex the beginning index, inclusive. + @param count the number of characters. + @return the specified substring. + + @since LibreOffice 3.7 + */ +SAL_DLLPUBLIC void SAL_CALL rtl_string_newFromSubString( + rtl_String ** newStr, const rtl_String * from, + sal_Int32 beginIndex, sal_Int32 count ) SAL_THROW_EXTERN_C(); + /** @internal @since LibreOffice 3.6 diff --git a/sal/inc/rtl/string.hxx b/sal/inc/rtl/string.hxx index 84ab48e05dc6..d58999b812f6 100644 --- a/sal/inc/rtl/string.hxx +++ b/sal/inc/rtl/string.hxx @@ -1024,31 +1024,27 @@ public: /** Returns a new string that is a substring of this string. - The substring begins at the specified beginIndex. It is an error for - beginIndex to be negative or to be greater than the length of this string. + The substring begins at the specified beginIndex. If + beginIndex is negative or be greater than the length of + this string, behaviour is undefined. @param beginIndex the beginning index, inclusive. @return the specified substring. */ OString copy( sal_Int32 beginIndex ) const SAL_THROW(()) { - assert(beginIndex >= 0 && beginIndex <= getLength()); - if ( beginIndex == 0 ) - return *this; - else - { - rtl_String* pNew = 0; - rtl_string_newFromStr_WithLength( &pNew, pData->buffer+beginIndex, getLength()-beginIndex ); - return OString( pNew, (DO_NOT_ACQUIRE*)0 ); - } + rtl_String *pNew = 0; + rtl_string_newFromSubString( &pNew, pData, beginIndex, getLength() - beginIndex ); + return OString( pNew, (DO_NOT_ACQUIRE*)0 ); } /** Returns a new string that is a substring of this string. The substring begins at the specified beginIndex and contains count - characters. It is an error for either beginIndex or count to be negative, - or for beginIndex + count to be greater than the length of this string. + characters. If either beginIndex or count are negative, + or beginIndex + count are greater than the length of this string + then behaviour is undefined. @param beginIndex the beginning index, inclusive. @param count the number of characters. @@ -1056,17 +1052,9 @@ public: */ OString copy( sal_Int32 beginIndex, sal_Int32 count ) const SAL_THROW(()) { - assert(beginIndex >= 0 && beginIndex <= getLength() && count >= 0 - && sal::static_int_cast(count) <= - sal::static_int_cast(getLength() - beginIndex)); - if ( (beginIndex == 0) && (count == getLength()) ) - return *this; - else - { - rtl_String* pNew = 0; - rtl_string_newFromStr_WithLength( &pNew, pData->buffer+beginIndex, count ); - return OString( pNew, (DO_NOT_ACQUIRE*)0 ); - } + rtl_String *pNew = 0; + rtl_string_newFromSubString( &pNew, pData, beginIndex, count ); + return OString( pNew, (DO_NOT_ACQUIRE*)0 ); } /** diff --git a/sal/inc/rtl/ustring.h b/sal/inc/rtl/ustring.h index 5b4982ec1461..231dcdce253a 100644 --- a/sal/inc/rtl/ustring.h +++ b/sal/inc/rtl/ustring.h @@ -1226,6 +1226,23 @@ SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromStr( SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromStr_WithLength( rtl_uString ** newStr, const sal_Unicode * value, sal_Int32 len ) SAL_THROW_EXTERN_C(); +/** Allocate a new string that is a substring of this string. + + The substring begins at the specified beginIndex and contains count + characters. Meaningless combinations such as negative beginIndex, + or beginIndex + count greater than the length of the string have + undefined behaviour. + + @param beginIndex the beginning index, inclusive. + @param count the number of characters. + @return the specified substring. + + @since LibreOffice 3.7 + */ +SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromSubString( + rtl_uString ** newStr, const rtl_uString * from, + sal_Int32 beginIndex, sal_Int32 count ) SAL_THROW_EXTERN_C(); + /** Allocate a new string that contains a copy of a character array. If the length of value is greater than zero, the reference count of the diff --git a/sal/inc/rtl/ustring.hxx b/sal/inc/rtl/ustring.hxx index b008054e17e3..e12a4b0b6256 100644 --- a/sal/inc/rtl/ustring.hxx +++ b/sal/inc/rtl/ustring.hxx @@ -1340,31 +1340,27 @@ public: /** Returns a new string that is a substring of this string. - The substring begins at the specified beginIndex. It is an error for - beginIndex to be negative or to be greater than the length of this string. + The substring begins at the specified beginIndex. If + beginIndex is negative or be greater than the length of + this string, behaviour is undefined. @param beginIndex the beginning index, inclusive. @return the specified substring. */ OUString copy( sal_Int32 beginIndex ) const SAL_THROW(()) { - assert(beginIndex >= 0 && beginIndex <= getLength()); - if ( beginIndex == 0 ) - return *this; - else - { - rtl_uString* pNew = 0; - rtl_uString_newFromStr_WithLength( &pNew, pData->buffer+beginIndex, getLength()-beginIndex ); - return OUString( pNew, (DO_NOT_ACQUIRE*)0 ); - } + rtl_uString *pNew = 0; + rtl_uString_newFromSubString( &pNew, pData, beginIndex, getLength() - beginIndex ); + return OUString( pNew, (DO_NOT_ACQUIRE*)0 ); } /** Returns a new string that is a substring of this string. The substring begins at the specified beginIndex and contains count - characters. It is an error for either beginIndex or count to be negative, - or for beginIndex + count to be greater than the length of this string. + characters. If either beginIndex or count are negative, + or beginIndex + count are greater than the length of this string + then behaviour is undefined. @param beginIndex the beginning index, inclusive. @param count the number of characters. @@ -1372,17 +1368,9 @@ public: */ OUString copy( sal_Int32 beginIndex, sal_Int32 count ) const SAL_THROW(()) { - assert(beginIndex >= 0 && beginIndex <= getLength() && count >= 0 - && sal::static_int_cast< sal_uInt32 >(count) <= - sal::static_int_cast< sal_uInt32 >(getLength() - beginIndex)); - if ( (beginIndex == 0) && (count == getLength()) ) - return *this; - else - { - rtl_uString* pNew = 0; - rtl_uString_newFromStr_WithLength( &pNew, pData->buffer+beginIndex, count ); - return OUString( pNew, (DO_NOT_ACQUIRE*)0 ); - } + rtl_uString *pNew = 0; + rtl_uString_newFromSubString( &pNew, pData, beginIndex, count ); + return OUString( pNew, (DO_NOT_ACQUIRE*)0 ); } /** diff --git a/sal/rtl/source/strtmpl.cxx b/sal/rtl/source/strtmpl.cxx index ebb0da199f2c..6069349bd36a 100644 --- a/sal/rtl/source/strtmpl.cxx +++ b/sal/rtl/source/strtmpl.cxx @@ -1194,6 +1194,29 @@ void SAL_CALL IMPL_RTL_STRINGNAME( newFromStr_WithLength )( IMPL_RTL_STRINGDATA* /* ----------------------------------------------------------------------- */ +void SAL_CALL IMPL_RTL_STRINGNAME( newFromSubString )( IMPL_RTL_STRINGDATA** ppThis, + const IMPL_RTL_STRINGDATA* pFrom, + sal_Int32 beginIndex, + sal_Int32 count ) + SAL_THROW_EXTERN_C() +{ + if ( beginIndex == 0 && count == pFrom->length ) + { + IMPL_RTL_STRINGNAME( assign )( ppThis, const_cast< IMPL_RTL_STRINGDATA * >( pFrom ) ); + return; + } + if ( count < 0 || beginIndex < 0 || beginIndex + count > pFrom->length ) + { + OSL_FAIL( "Out of bounds substring access" ); + IMPL_RTL_STRINGNAME( newFromLiteral )( ppThis, "!!br0ken!!", 10, 0 ); + return; + } + + IMPL_RTL_STRINGNAME( newFromStr_WithLength )( ppThis, pFrom->buffer + beginIndex, count ); +} + +/* ----------------------------------------------------------------------- */ + // Used when creating from string literals. void SAL_CALL IMPL_RTL_STRINGNAME( newFromLiteral )( IMPL_RTL_STRINGDATA** ppThis, const sal_Char* pCharStr, diff --git a/sal/util/sal.map b/sal/util/sal.map index 7a431c3872d9..9efed6aaea9a 100644 --- a/sal/util/sal.map +++ b/sal/util/sal.map @@ -627,6 +627,12 @@ LIBO_UDK_3.6 { # symbols available in >= LibO 3.6 rtl_uStringBuffer_makeStringAndClear; } UDK_3.10; +LIBO_UDK_3.7 { # symbols available in >= LibO 3.7 + global: + rtl_string_newFromSubString; + rtl_uString_newFromSubString; +} UDK_3.10; + PRIVATE_1.0 { global: osl_detail_ObjectRegistry_storeAddresses; -- cgit