diff options
author | Katarina Behrens <Katarina.Behrens@cib.de> | 2015-10-26 18:36:49 +0100 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2015-11-16 19:53:07 +0000 |
commit | c3293e0eaae39f189fd554a39c130738e107431e (patch) | |
tree | 7e7fe2606b18c6172a27ec0226dad607e0409f72 | |
parent | 055c248e1573cc7cd7988b28f8bb0bf64bf0d6c8 (diff) |
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/19610
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Eike Rathke <erack@redhat.com>
Reviewed-on: https://gerrit.libreoffice.org/19983
Tested-by: Jenkins <ci@libreoffice.org>
-rw-r--r-- | sc/qa/unit/subsequent_export-test.cxx | 32 | ||||
-rw-r--r-- | sc/source/filter/excel/excdoc.cxx | 12 | ||||
-rw-r--r-- | sc/source/ui/unoobj/confuno.cxx | 16 |
3 files changed, 51 insertions, 9 deletions
diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx index b21b4aa9fa1f..b1db15933e58 100644 --- a/sc/qa/unit/subsequent_export-test.cxx +++ b/sc/qa/unit/subsequent_export-test.cxx @@ -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(); diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx index 98fc175cff4d..6bbced156e50 100644 --- a/sc/source/filter/excel/excdoc.cxx +++ b/sc/source/filter/excel/excdoc.cxx @@ -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); } diff --git a/sc/source/ui/unoobj/confuno.cxx b/sc/source/ui/unoobj/confuno.cxx index 0ddaaa114f35..36510022e37f 100644 --- a/sc/source/ui/unoobj/confuno.cxx +++ b/sc/source/ui/unoobj/confuno.cxx @@ -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: |