summaryrefslogtreecommitdiff
path: root/basic
diff options
context:
space:
mode:
authorAndreas Heinisch <andreas.heinisch@yahoo.de>2020-03-21 14:59:27 +0100
committerMike Kaganski <mike.kaganski@collabora.com>2020-03-24 09:30:38 +0100
commit16b0bbb671a8080655e27542e576478486810404 (patch)
treee52bdd72fbc33308ba9ced4dfdaf0a0258dacc35 /basic
parent2846686272931cd8bb0bcd452dd0e8b5b52064b1 (diff)
tdf#131296: get numeric value with its data type in StepLOADNC
In order to load numeric values, generate SbiOpcode::NUMBER_ opcodes including the numeric value and its data type instead of SbiOpcode::CONST_. The numeric value and its data type will be restored in SbiRuntime::StepLOADNC. When the new compiled code is stored in documents, e.g. password-protected libraries, leagcy LO versions will just read up to non-numeric characters, thus correctly obtaining number value and ignoring the type, so the change is backward-compatible. To interpret legacy compiled code, old treatment of SbiRuntime::StepLOADI is restored, reverting commit 0b4f8bf571baf2ccd5a8aafdc4deb41867420be3. This change reimplements the fix for tdf#129596. Change-Id: I46ebfc77f9bea69479968950c0fb7264e4a7ab27 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/90858 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'basic')
-rw-r--r--basic/source/comp/exprgen.cxx8
-rw-r--r--basic/source/comp/symtbl.cxx11
-rw-r--r--basic/source/runtime/runtime.cxx35
3 files changed, 30 insertions, 24 deletions
diff --git a/basic/source/comp/exprgen.cxx b/basic/source/comp/exprgen.cxx
index 3981bef2fb5e..6c60c02b0d7e 100644
--- a/basic/source/comp/exprgen.cxx
+++ b/basic/source/comp/exprgen.cxx
@@ -72,16 +72,14 @@ void SbiExprNode::Gen( SbiCodeGen& rGen, RecursiveMode eRecMode )
case SbxEMPTY:
rGen.Gen( SbiOpcode::EMPTY_ );
break;
- case SbxLONG:
- case SbxINTEGER:
- nStringId = rGen.GetParser()->aGblStrings.Add(nVal, eType);
- rGen.Gen( SbiOpcode::CONST_, nStringId );
- break;
case SbxSTRING:
nStringId = rGen.GetParser()->aGblStrings.Add( aStrVal );
rGen.Gen( SbiOpcode::SCONST_, nStringId );
break;
default:
+ // tdf#131296 - generate SbiOpcode::NUMBER_ instead of SbiOpcode::CONST_
+ // for SbxINTEGER and SbxLONG including their numeric value and its data type,
+ // which will be restored in SbiRuntime::StepLOADNC.
nStringId = rGen.GetParser()->aGblStrings.Add( nVal, eType );
rGen.Gen( SbiOpcode::NUMBER_, nStringId );
break;
diff --git a/basic/source/comp/symtbl.cxx b/basic/source/comp/symtbl.cxx
index b05575adfdfb..ac6f1ecd29da 100644
--- a/basic/source/comp/symtbl.cxx
+++ b/basic/source/comp/symtbl.cxx
@@ -66,10 +66,13 @@ short SbiStringPool::Add( double n, SbxDataType t )
char buf[ 40 ];
switch( t )
{
- case SbxINTEGER: snprintf( buf, sizeof(buf), "%d", static_cast<short>(n) ); break;
- case SbxLONG: snprintf( buf, sizeof(buf), "%ld", static_cast<long>(n) ); break;
- case SbxSINGLE: snprintf( buf, sizeof(buf), "%.6g", static_cast<float>(n) ); break;
- case SbxDOUBLE: snprintf( buf, sizeof(buf), "%.16g", n ); break;
+ // tdf#131296 - store numeric value including its type character
+ // See GetSuffixType in basic/source/comp/scanner.cxx for type characters
+ case SbxINTEGER: snprintf( buf, sizeof(buf), "%d%%", static_cast<short>(n) ); break;
+ case SbxLONG: snprintf( buf, sizeof(buf), "%ld&", static_cast<long>(n) ); break;
+ case SbxSINGLE: snprintf( buf, sizeof(buf), "%.6g!", static_cast<float>(n) ); break;
+ case SbxDOUBLE: snprintf( buf, sizeof(buf), "%.16g", n ); break; // default processing in SbiRuntime::StepLOADNC - no type character
+ case SbxCURRENCY: snprintf(buf, sizeof(buf), "%.16g@", n); break;
default: break;
}
return Add( OUString::createFromAscii( buf ) );
diff --git a/basic/source/runtime/runtime.cxx b/basic/source/runtime/runtime.cxx
index ffd03f28b7cf..15b45ec736a0 100644
--- a/basic/source/runtime/runtime.cxx
+++ b/basic/source/runtime/runtime.cxx
@@ -2773,8 +2773,6 @@ void SbiRuntime::StepERROR()
void SbiRuntime::StepLOADNC( sal_uInt32 nOp1 )
{
- SbxVariable* p = new SbxVariable( SbxDOUBLE );
-
// #57844 use localized function
OUString aStr = pImg->GetString( static_cast<short>( nOp1 ) );
// also allow , !!!
@@ -2783,8 +2781,24 @@ void SbiRuntime::StepLOADNC( sal_uInt32 nOp1 )
{
aStr = aStr.replaceAt(iComma, 1, ".");
}
- double n = ::rtl::math::stringToDouble( aStr, '.', ',' );
+ sal_Int32 nParseEnd = 0;
+ rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok;
+ double n = ::rtl::math::stringToDouble( aStr, '.', ',', &eStatus, &nParseEnd );
+ // tdf#131296 - retrieve data type put in SbiExprNode::Gen
+ SbxDataType eType = SbxDOUBLE;
+ if ( nParseEnd < aStr.getLength() )
+ {
+ switch ( aStr[nParseEnd] )
+ {
+ // See GetSuffixType in basic/source/comp/scanner.cxx for type characters
+ case '%': eType = SbxINTEGER; break;
+ case '&': eType = SbxLONG; break;
+ case '!': eType = SbxSINGLE; break;
+ case '@': eType = SbxCURRENCY; break;
+ }
+ }
+ SbxVariable* p = new SbxVariable( eType );
p->PutDouble( n );
PushVar( p );
}
@@ -2799,22 +2813,13 @@ void SbiRuntime::StepLOADSC( sal_uInt32 nOp1 )
}
// Immediate Load (+value)
+// The opcode is not generated in SbiExprNode::Gen anymore; used for legacy images
void SbiRuntime::StepLOADI( sal_uInt32 nOp1 )
{
SbxVariable* p = new SbxVariable;
-
- OUString aStr = pImg->GetString(static_cast<short>(nOp1));
- double n = ::rtl::math::stringToDouble(aStr, '.', ',');
- if (n >= SbxMININT && n <= SbxMAXINT)
- {
- p->PutInteger(static_cast<sal_Int16>(n));
- }
- else
- {
- p->PutLong(static_cast<sal_Int32>(n));
- }
- PushVar(p);
+ p->PutInteger( static_cast<sal_Int16>( nOp1 ) );
+ PushVar( p );
}
// store a named argument in Argv (+Arg-no. from 1!)