[libreoffice/f17] Resolves: rhbz#919020 Basic CDbl() and CSng() scan localized number
Eike Rathke
erack at fedoraproject.org
Mon Apr 22 18:23:14 UTC 2013
commit 16b3dedc2cd5b423f3684dae19dc9a29dcc9f940
Author: Eike Rathke <erack at redhat.com>
Date: Mon Apr 22 20:15:50 2013 +0200
Resolves: rhbz#919020 Basic CDbl() and CSng() scan localized number
Replaces 1ca7cc38ae5cbe523a6c65b0169330ed0fd212df
...fixed-a-possible-crasher-in-basic-runtime.patch | 104 ------
...bz-919020-Basic-CDbl-and-CSng-scan-locali.patch | 341 ++++++++++++++++++++
libreoffice.spec | 13 +-
3 files changed, 349 insertions(+), 109 deletions(-)
---
diff --git a/0001-resolved-rhbz-919020-Basic-CDbl-and-CSng-scan-locali.patch b/0001-resolved-rhbz-919020-Basic-CDbl-and-CSng-scan-locali.patch
new file mode 100644
index 0000000..cb91eae
--- /dev/null
+++ b/0001-resolved-rhbz-919020-Basic-CDbl-and-CSng-scan-locali.patch
@@ -0,0 +1,341 @@
+From 8bf4c57f57851888360736d41342abb9623480f0 Mon Sep 17 00:00:00 2001
+Message-Id: <8bf4c57f57851888360736d41342abb9623480f0.1366653663.git.erack at redhat.com>
+From: Eike Rathke <erack at redhat.com>
+Date: Tue, 19 Mar 2013 23:23:16 +0100
+Subject: [PATCH] resolved rhbz#919020 Basic CDbl() and CSng() scan localized
+ number
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="------------erAck-patch-parts"
+
+This is a multi-part message in MIME format.
+--------------erAck-patch-parts
+Content-Type: text/plain; charset=UTF-8; format=fixed
+Content-Transfer-Encoding: 8bit
+
+
+Code wrongly replaced decimal separator with '.' and used atof() to scan
+the number string which itself may be localized on *iX systems but not
+on Windows. Hence on *iX the numbers may had been truncated where on
+Windows they were not.
+
+Additionally made this work with Unicode separators if defined for the
+locale, removed the awkward conversion to ASCII byte string and
+eliminated use of toupper() and isdigit() calls. Also eliminated a
+possible buffer overflow.
+
+(cherry picked from commit 9e9f39d171cafa035d7b8e74187e25c3581cb89d)
+
+Conflicts:
+ basic/source/sbx/sbxscan.cxx
+
+replace decimal separator at correct position, rhbz#919020
+
+(cherry picked from commit e96c7a60c88bc1e3008ebdeafd59327933d6707f)
+
+Reviewed-on: https://gerrit.libreoffice.org/2859
+Reviewed-by: Noel Power <noel.power at suse.com>
+Tested-by: Noel Power <noel.power at suse.com>
+(cherry picked from commit 96b079e24f86f7f49a624573783c6e103012f942)
+
+Conflicts:
+ basic/source/sbx/sbxscan.cxx
+
+Change-Id: I35d82e8f267ecb925783bf6f2de044a29c08f688
+---
+ basic/source/sbx/sbxscan.cxx | 203 ++++++++++++++++++++++++++-----------------
+ 1 file changed, 121 insertions(+), 82 deletions(-)
+
+
+--------------erAck-patch-parts
+Content-Type: text/x-patch; name="0001-resolved-rhbz-919020-Basic-CDbl-and-CSng-scan-locali.patch"
+Content-Transfer-Encoding: 8bit
+Content-Disposition: attachment; filename="0001-resolved-rhbz-919020-Basic-CDbl-and-CSng-scan-locali.patch"
+
+diff --git a/basic/source/sbx/sbxscan.cxx b/basic/source/sbx/sbxscan.cxx
+index 50e4e6c..3a0584d 100644
+--- a/basic/source/sbx/sbxscan.cxx
++++ b/basic/source/sbx/sbxscan.cxx
+@@ -62,108 +62,131 @@ void ImpGetIntntlSep( sal_Unicode& rcDecimalSep, sal_Unicode& rcThousandSep )
+ rcThousandSep = rData.getNumThousandSep().GetBuffer()[0];
+ }
+
++inline bool ImpIsDigit( sal_Unicode c )
++{
++ return '0' <= c && c <= '9';
++}
++
++/** NOTE: slightly differs from strchr() in that it does not consider the
++ terminating NULL character to be part of the string and returns bool
++ instead of pointer, if character is 0 returns false.
++ */
++bool ImpStrChr( const sal_Unicode* p, sal_Unicode c )
++{
++ if (!c)
++ return false;
++ while (*p)
++ {
++ if (*p++ == c)
++ return true;
++ }
++ return false;
++}
++
++bool ImpIsAlNum( sal_Unicode c )
++{
++ return (c < 128) ? isalnum( static_cast<char>(c) ) : false;
++}
++
+ // scanning a string according to BASIC-conventions
+-// but exponent may also be a D, so data type is SbxDOUBLED
++// but exponent may also be a D, so data type is SbxDOUBLE
+ // conversion error if data type is fixed and it doesn't fit
+
+ SbxError ImpScan( const ::rtl::OUString& rWSrc, double& nVal, SbxDataType& rType,
+ sal_uInt16* pLen, sal_Bool bAllowIntntl, sal_Bool bOnlyIntntl )
+ {
+- ::rtl::OString aBStr( ::rtl::OUStringToOString( rWSrc, RTL_TEXTENCODING_ASCII_US ) );
+-
+- char cIntntlComma, cIntntl1000;
+- char cNonIntntlComma = '.';
+-
+- sal_Unicode cDecimalSep, cThousandSep = 0;
++ sal_Unicode cIntntlDecSep, cIntntlGrpSep;
++ sal_Unicode cNonIntntlDecSep = '.';
+ if( bAllowIntntl || bOnlyIntntl )
+ {
+- ImpGetIntntlSep( cDecimalSep, cThousandSep );
+- cIntntlComma = (char)cDecimalSep;
+- cIntntl1000 = (char)cThousandSep;
++ ImpGetIntntlSep( cIntntlDecSep, cIntntlGrpSep );
++ if( bOnlyIntntl )
++ cNonIntntlDecSep = cIntntlDecSep;
+ }
+-
+ else
+ {
+- cIntntlComma = cNonIntntlComma;
+- cIntntl1000 = cNonIntntlComma;
++ cIntntlDecSep = cNonIntntlDecSep;
++ cIntntlGrpSep = 0; // no group separator accepted in non-i18n
+ }
+
+- if( bOnlyIntntl )
+- {
+- cNonIntntlComma = cIntntlComma;
+- cIntntl1000 = (char)cThousandSep;
+- }
+-
+- const char* pStart = aBStr.getStr();
+- const char* p = pStart;
+- char buf[ 80 ], *q = buf;
+- sal_Bool bRes = sal_True;
+- sal_Bool bMinus = sal_False;
++ const sal_Unicode* const pStart = rWSrc.getStr();
++ const sal_Unicode* p = pStart;
++ rtl::OUStringBuffer aBuf( rWSrc.getLength());
++ bool bRes = true;
++ bool bMinus = false;
+ nVal = 0;
+ SbxDataType eScanType = SbxSINGLE;
+- while( *p &&( *p == ' ' || *p == '\t' ) ) p++;
++ while( *p == ' ' || *p == '\t' )
++ p++;
+ if( *p == '-' )
+- p++, bMinus = sal_True;
+- if( isdigit( *p ) ||( (*p == cNonIntntlComma || *p == cIntntlComma ||
+- *p == cIntntl1000) && isdigit( *(p+1 ) ) ) )
++ {
++ p++;
++ bMinus = true;
++ }
++ if( ImpIsDigit( *p ) || ((*p == cNonIntntlDecSep || *p == cIntntlDecSep ||
++ (cIntntlDecSep && *p == cIntntlGrpSep)) && ImpIsDigit( *(p+1) )))
+ {
+ short exp = 0;
+- short comma = 0;
++ short decsep = 0;
+ short ndig = 0;
+ short ncdig = 0; // number of digits after decimal point
+- rtl::OStringBuffer aSearchStr(RTL_CONSTASCII_STRINGPARAM("0123456789DEde"));
+- aSearchStr.append(cNonIntntlComma);
+- if( cIntntlComma != cNonIntntlComma )
+- aSearchStr.append(cIntntlComma);
++ rtl::OUStringBuffer aSearchStr( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("0123456789DEde")));
++ aSearchStr.append(cNonIntntlDecSep);
++ if( cIntntlDecSep != cNonIntntlDecSep )
++ aSearchStr.append(cIntntlDecSep);
+ if( bOnlyIntntl )
+- aSearchStr.append(cIntntl1000);
+- const char* pSearchStr = aSearchStr.getStr();
+- while( strchr( pSearchStr, *p ) && *p )
++ aSearchStr.append(cIntntlGrpSep);
++ const sal_Unicode* const pSearchStr = aSearchStr.getStr();
++ const sal_Unicode pDdEe[] = { 'D', 'd', 'E', 'e', 0 };
++ while( ImpStrChr( pSearchStr, *p ) )
+ {
+- if( bOnlyIntntl && *p == cIntntl1000 )
++ aBuf.append( *p );
++ if( bOnlyIntntl && *p == cIntntlGrpSep )
+ {
+ p++;
+ continue;
+ }
+-
+- if( *p == cNonIntntlComma || *p == cIntntlComma )
++ if( *p == cNonIntntlDecSep || *p == cIntntlDecSep )
+ {
+- // always insert '.' so that atof works
++ // Use the separator that is passed to stringToDouble()
++ aBuf[ p - pStart ] = cIntntlDecSep;
+ p++;
+- if( ++comma > 1 )
++ if( ++decsep > 1 )
+ continue;
+- else
+- *q++ = '.';
+ }
+- else if( strchr( "DdEe", *p ) )
++ else if( ImpStrChr( pDdEe, *p ) )
+ {
+ if( ++exp > 1 )
+ {
+- p++; continue;
++ p++;
++ continue;
+ }
+- if( toupper( *p ) == 'D' )
++ if( *p == 'D' || *p == 'd' )
+ eScanType = SbxDOUBLE;
+- *q++ = 'E'; p++;
+-
+- if( *p == '+' )
+- p++;
+- else
+- if( *p == '-' )
+- *q++ = *p++;
++ aBuf[ p - pStart ] = 'E';
++ p++;
+ }
+ else
+ {
+- *q++ = *p++;
+- if( comma && !exp ) ncdig++;
++ p++;
++ if( decsep && !exp )
++ ncdig++;
+ }
+- if( !exp ) ndig++;
++ if( !exp )
++ ndig++;
+ }
+- *q = 0;
+
+- if( comma > 1 || exp > 1 )
+- bRes = sal_False;
++ if( decsep > 1 || exp > 1 )
++ bRes = false;
++
++ rtl::OUString aBufStr( aBuf.makeStringAndClear());
++ rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok;
++ sal_Int32 nParseEnd = 0;
++ nVal = rtl::math::stringToDouble( aBufStr, cIntntlDecSep, cIntntlGrpSep, &eStatus, &nParseEnd );
++ if( eStatus != rtl_math_ConversionStatus_Ok || nParseEnd != aBufStr.getLength() )
++ bRes = false;
+
+- if( !comma && !exp )
++ if( !decsep && !exp )
+ {
+ if( nVal >= SbxMININT && nVal <= SbxMAXINT )
+ eScanType = SbxINTEGER;
+@@ -171,49 +194,65 @@ SbxError ImpScan( const ::rtl::OUString& rWSrc, double& nVal, SbxDataType& rType
+ eScanType = SbxLONG;
+ }
+
+- nVal = atof( buf );
+- ndig = ndig - comma;
++ ndig = ndig - decsep;
+ // too many numbers for SINGLE?
+ if( ndig > 15 || ncdig > 6 )
+ eScanType = SbxDOUBLE;
+
+ // type detection?
+- if( strchr( "%!&#", *p ) && *p ) p++;
++ const sal_Unicode pTypes[] = { '%', '!', '&', '#', 0 };
++ if( ImpStrChr( pTypes, *p ) )
++ p++;
+ }
+ // hex/octal number? read in and convert:
+ else if( *p == '&' )
+ {
+ p++;
+ eScanType = SbxLONG;
+- const char *cmp = "0123456789ABCDEF";
++ rtl::OUString aCmp( RTL_CONSTASCII_USTRINGPARAM("0123456789ABCDEFabcdef") );
+ char base = 16;
+ char ndig = 8;
+- char xch = *p++;
+- switch( toupper( xch ) )
++ switch( *p++ )
+ {
+- case 'O': cmp = "01234567"; base = 8; ndig = 11; break;
+- case 'H': break;
+- default : bRes = sal_False;
++ case 'O':
++ case 'o':
++ aCmp = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("01234567"));
++ base = 8;
++ ndig = 11;
++ break;
++ case 'H':
++ case 'h':
++ break;
++ default :
++ bRes = false;
+ }
+- long l = 0;
+- int i;
+- while( isalnum( *p ) )
++ const sal_Unicode* const pCmp = aCmp.getStr();
++ while( ImpIsAlNum( *p ) ) /* XXX: really munge all alnum also when error? */
+ {
+- char ch = sal::static_int_cast< char >( toupper( *p ) );
++ sal_Unicode ch = *p;
++ if( ImpStrChr( pCmp, ch ) )
++ {
++ if (ch > 0x60)
++ ch -= 0x20; // convert ASCII lower to upper case
++ aBuf.append( ch );
++ }
++ else
++ bRes = false;
+ p++;
+- if( strchr( cmp, ch ) ) *q++ = ch;
+- else bRes = sal_False;
+ }
+- *q = 0;
+- for( q = buf; *q; q++ )
++ rtl::OUString aBufStr( aBuf.makeStringAndClear());
++ long l = 0;
++ for( const sal_Unicode* q = aBufStr.getStr(); bRes && *q; q++ )
+ {
+- i =( *q & 0xFF ) - '0';
+- if( i > 9 ) i -= 7;
+- l =( l * base ) + i;
++ int i = *q - '0';
++ if( i > 9 )
++ i -= 7; // 'A'-'0' = 17 => 10, ...
++ l = ( l * base ) + i;
+ if( !ndig-- )
+- bRes = sal_False;
++ bRes = false;
+ }
+- if( *p == '&' ) p++;
++ if( *p == '&' )
++ p++;
+ nVal = (double) l;
+ if( l >= SbxMININT && l <= SbxMAXINT )
+ eScanType = SbxINTEGER;
+
+--------------erAck-patch-parts--
+
+
diff --git a/libreoffice.spec b/libreoffice.spec
index dd9724c..3425b05 100644
--- a/libreoffice.spec
+++ b/libreoffice.spec
@@ -35,7 +35,7 @@ Summary: Free Software Productivity Suite
Name: libreoffice
Epoch: 1
Version: %{libo_version}.2
-Release: 11%{?dist}
+Release: 12%{?dist}
License: (MPLv1.1 or LGPLv3+) and LGPLv3 and LGPLv2+ and BSD and (MPLv1.1 or GPLv2 or LGPLv2 or Netscape) and Public Domain and ASL 2.0 and Artistic
Group: Applications/Productivity
URL: http://www.documentfoundation.org/develop
@@ -181,8 +181,8 @@ Patch63: 0001-Resolves-fdo-48569-crash-on-export-to-.docx-of-inlin.patch
Patch64: 0001-rhbz-760765-copy-custom-styles-on-copy-paste.patch
Patch65: 0001-fdo-53175-Fixed-the-end-of-hyperlinks.patch
Patch66: 0001-Fix-fdo-47669-also-check-if-we-started-the-tag-befor.patch
-Patch67: 0001-fixed-a-possible-crasher-in-basic-runtime.patch
-Patch68: 0001-Resolves-rhbz-907933-crash-on-removing-second-last-p.patch
+Patch67: 0001-Resolves-rhbz-907933-crash-on-removing-second-last-p.patch
+Patch68: 0001-resolved-rhbz-919020-Basic-CDbl-and-CSng-scan-locali.patch
%{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
%define instdir %{_libdir}
@@ -1079,8 +1079,8 @@ mv -f redhat.soc extras/source/palettes/standard.soc
%patch64 -p1 -b .rhbz-760765-copy-custom-styles-on-copy-paste.patch
%patch65 -p1 -b .fdo-53175-Fixed-the-end-of-hyperlinks.patch
%patch66 -p1 -b .Fix-fdo-47669-also-check-if-we-started-the-tag-befor.patch
-%patch67 -p1 -b .fixed-a-possible-crasher-in-basic-runtime.patch
-%patch68 -p1 -b .rhbz-907933-crash-on-removing-second-last-p.patch
+%patch67 -p1 -b .rhbz-907933-crash-on-removing-second-last-p.patch
+%patch68 -p1 -b .rhbz-919020-Basic-CDbl-and-CSng-scan-locali.patch
# TODO: check this
# these are horribly incomplete--empty translations and copied english
@@ -2367,6 +2367,9 @@ update-desktop-database %{_datadir}/applications &> /dev/null || :
%endif
%changelog
+* Mon Apr 22 2013 Eike Rathke <erack at redhat.com> - 1:3.5.7.2-12
+- Resolves: rhbz#919020 Basic CDbl() and CSng() scan localized number
+
* Thu Apr 04 2013 Caolán McNamara <caolanm at redhat.com> - 1:3.5.7.2-11
- Resolves: rhbz#928786 crash on deleting certain table rows
More information about the scm-commits
mailing list