Kaydet (Commit) fd0f5e55 authored tarafından Katarina Behrens's avatar Katarina Behrens Kaydeden (comit) Andras Timar

tdf#92256: Don't save CONV_UNSPECIFIED string ref syntax value

The following scenario is how it breaks:
1. user has ExcelA1 as her formula syntax setting, CONV_UNSPECIFIED
(that means "same as formula syntax") as her string ref syntax setting
2. she saves the document, it will now contain CONV_UNSPECIFIED value
3. someone else with CalcA1 formula syntax setting opens the document
... since it contains CONV_UNSPECIFIED "same as formula syntax" value,
it will use his CalcA1 formula syntax value to evaluate INDIRECT func
=> #REF!

Avoid this by reading formula syntax/grammar value, mapping it to
matching string ref syntax and saving that instead of CONV_UNSPECIFIED

Change-Id: Ide62d81e6b70c2e9f2ff79648935788107475778
Reviewed-on: https://gerrit.libreoffice.org/19610Reviewed-by: 's avatarEike Rathke <erack@redhat.com>
Tested-by: 's avatarEike Rathke <erack@redhat.com>
Reviewed-on: https://gerrit.libreoffice.org/19983Tested-by: 's avatarJenkins <ci@libreoffice.org>
(cherry picked from commit c3293e0e)
üst 822a962c
......@@ -150,7 +150,7 @@ public:
void testMatrixMultiplication();
void testRefStringXLSX();
void testRefStringConfigXLSX();
void testRefStringUnspecified();
CPPUNIT_TEST_SUITE(ScExportTest);
CPPUNIT_TEST(test);
......@@ -210,7 +210,7 @@ public:
CPPUNIT_TEST(testMatrixMultiplication);
CPPUNIT_TEST(testRefStringXLSX);
CPPUNIT_TEST(testRefStringConfigXLSX);
CPPUNIT_TEST(testRefStringUnspecified);
CPPUNIT_TEST_SUITE_END();
......@@ -2915,6 +2915,34 @@ void ScExportTest::testRefStringConfigXLSX()
xNewDocSh->DoClose();
}
void ScExportTest::testRefStringUnspecified()
{
ScDocShell* pShell = new ScDocShell(
SfxModelFlags::EMBEDDED_OBJECT |
SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS |
SfxModelFlags::DISABLE_DOCUMENT_RECOVERY);
pShell->DoInitNew();
ScDocument& rDoc = pShell->GetDocument();
ScCalcConfig aConfig = rDoc.GetCalcConfig();
CPPUNIT_ASSERT_EQUAL_MESSAGE("Default string ref syntax value doesn't match", formula::FormulaGrammar::CONV_UNSPECIFIED,
aConfig.meStringRefAddressSyntax);
// change formula syntax (i.e. not string ref syntax) to ExcelA1
rDoc.SetGrammar( formula::FormulaGrammar::GRAM_NATIVE_XL_A1 );
ScDocShellRef xDocSh = saveAndReload( pShell, ODS );
CPPUNIT_ASSERT_MESSAGE("Failed to reload doc", xDocSh.Is());
// with string ref syntax at its default value, we should've saved ExcelA1
ScDocument& rDoc2 = xDocSh->GetDocument();
aConfig = rDoc2.GetCalcConfig();
CPPUNIT_ASSERT_EQUAL_MESSAGE("String ref syntax doesn't match", formula::FormulaGrammar::CONV_XL_A1,
aConfig.meStringRefAddressSyntax);
xDocSh->DoClose();
}
CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest);
CPPUNIT_PLUGIN_IMPLEMENT();
......
......@@ -882,15 +882,23 @@ void ExcDocument::WriteXml( XclExpXmlStream& rStrm )
rCaches.SaveXml(rStrm);
const ScCalcConfig& rCalcConfig = GetDoc().GetCalcConfig();
formula::FormulaGrammar::AddressConvention eConv = rCalcConfig.meStringRefAddressSyntax;
// don't save "unspecified" string ref syntax ... query formula grammar
// and save that instead
if( eConv == formula::FormulaGrammar::CONV_UNSPECIFIED)
{
eConv = GetDoc().GetAddressConvention();
}
// write if it has been read|imported or explicitly changed
// or if ref syntax isn't what would be native for our file format
// i.e. ExcelA1 in this case
if ( rCalcConfig.mbHasStringRefSyntax ||
(rCalcConfig.meStringRefAddressSyntax != formula::FormulaGrammar::CONV_XL_A1) )
(eConv != formula::FormulaGrammar::CONV_XL_A1) )
{
XclExtLstRef xExtLst( new XclExtLst( GetRoot() ) );
xExtLst->AddRecord( XclExpExtRef( new XclExpExtCalcPr( GetRoot(), rCalcConfig.meStringRefAddressSyntax )) );
xExtLst->AddRecord( XclExpExtRef( new XclExpExtCalcPr( GetRoot(), eConv )) );
xExtLst->SaveXml(rStrm);
}
......
......@@ -461,22 +461,28 @@ uno::Any SAL_CALL ScDocumentConfiguration::getPropertyValue( const OUString& aPr
else if ( aPropertyName == SC_UNO_SYNTAXSTRINGREF )
{
ScCalcConfig aCalcConfig = rDoc.GetCalcConfig();
formula::FormulaGrammar::AddressConvention eConv = aCalcConfig.meStringRefAddressSyntax;
// don't save "unspecified" string ref syntax ... query formula grammar
// and save that instead
if( eConv == formula::FormulaGrammar::CONV_UNSPECIFIED)
{
eConv = rDoc.GetAddressConvention();
}
// write if it has been read|imported or explicitly changed
// or if ref syntax isn't what would be native for our file format
// i.e. CalcA1 in this case
if ( aCalcConfig.mbHasStringRefSyntax ||
(aCalcConfig.meStringRefAddressSyntax != formula::FormulaGrammar::CONV_OOO) )
(eConv != formula::FormulaGrammar::CONV_OOO) )
{
formula::FormulaGrammar::AddressConvention aConv = aCalcConfig.meStringRefAddressSyntax;
switch (aConv)
switch (eConv)
{
case formula::FormulaGrammar::CONV_OOO:
case formula::FormulaGrammar::CONV_XL_A1:
case formula::FormulaGrammar::CONV_XL_R1C1:
case formula::FormulaGrammar::CONV_A1_XL_A1:
aRet <<= static_cast<sal_Int16>( aConv );
aRet <<= static_cast<sal_Int16>( eConv );
break;
case formula::FormulaGrammar::CONV_UNSPECIFIED:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment