summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2014-01-01 14:06:05 +0000
committerMichael Meeks <michael.meeks@collabora.com>2014-01-02 10:57:27 +0000
commitd17a83fa549f828f29e6939b16ba8b568a75f95e (patch)
tree2fb43a22f55a14fb9d7fb7cc5420a212fec3178f
parent1b66c17b7fa7b0c6d74d03777e24db236bb86282 (diff)
oox: fix crash with threaded xlsx loading by pre-allocating sheet storage.
Change-Id: I12c8afe6467bf3ae755faf8c6d01c6aa37d5be27
-rw-r--r--sc/source/filter/inc/formulabuffer.hxx40
-rw-r--r--sc/source/filter/oox/formulabuffer.cxx51
-rw-r--r--sc/source/filter/oox/workbookfragment.cxx6
3 files changed, 55 insertions, 42 deletions
diff --git a/sc/source/filter/inc/formulabuffer.hxx b/sc/source/filter/inc/formulabuffer.hxx
index 2411466787d0..6be0a25cc201 100644
--- a/sc/source/filter/inc/formulabuffer.hxx
+++ b/sc/source/filter/inc/formulabuffer.hxx
@@ -91,21 +91,21 @@ public:
};
private:
- typedef ::std::map< SCTAB, std::vector<TokenAddressItem> > FormulaDataMap;
- typedef ::std::map< SCTAB, std::vector<TokenRangeAddressItem> > ArrayFormulaDataMap;
+ // Vectors indexed by SCTAB - cf. SetSheetCount
+ typedef ::std::vector< std::vector<TokenAddressItem> > FormulaDataArray;
+ typedef ::std::vector< std::vector<TokenRangeAddressItem> > ArrayFormulaDataArray;
// sheet -> list of shared formula descriptions
- typedef ::std::map< SCTAB, std::vector<SharedFormulaDesc> > SheetToSharedFormulaid;
+ typedef ::std::vector< std::vector<SharedFormulaDesc> > SheetToSharedFormulaid;
// sheet -> stuff needed to create shared formulae
- typedef ::std::map< SCTAB, std::vector<SharedFormulaEntry> > SheetToFormulaEntryMap;
-
- typedef ::std::map< SCTAB, std::vector<ValueAddressPair> > FormulaValueMap;
+ typedef ::std::vector< std::vector<SharedFormulaEntry> > SheetToFormulaEntryArray;
+ typedef ::std::vector< std::vector<ValueAddressPair> > FormulaValueArray;
osl::Mutex maMtxData;
- FormulaDataMap maCellFormulas;
- ArrayFormulaDataMap maCellArrayFormulas;
- SheetToFormulaEntryMap maSharedFormulas;
- SheetToSharedFormulaid maSharedFormulaIds;
- FormulaValueMap maCellFormulaValues;
+ FormulaDataArray maCellFormulas;
+ ArrayFormulaDataArray maCellArrayFormulas;
+ SheetToFormulaEntryArray maSharedFormulas;
+ SheetToSharedFormulaid maSharedFormulaIds;
+ FormulaValueArray maCellFormulaValues;
SheetItem getSheetItem( SCTAB nTab );
@@ -118,14 +118,20 @@ public:
const ::com::sun::star::table::CellAddress& rAddress, sal_Int32 nSharedId,
const OUString& rCellValue, sal_Int32 nValueType );
- void setCellFormulaValue( const ::com::sun::star::table::CellAddress& rAddress, double fValue );
- void setCellArrayFormula( const ::com::sun::star::table::CellRangeAddress& rRangeAddress, const ::com::sun::star::table::CellAddress& rTokenAddress, const OUString& );
- void createSharedFormulaMapEntry(
- const com::sun::star::table::CellAddress& rAddress,
- const com::sun::star::table::CellRangeAddress& rRange,
- sal_Int32 nSharedId, const OUString& rTokens );
+ void setCellFormulaValue( const ::css::table::CellAddress& rAddress,
+ double fValue );
+ void setCellArrayFormula( const ::css::table::CellRangeAddress& rRangeAddress,
+ const ::css::table::CellAddress& rTokenAddress,
+ const OUString& );
+ void createSharedFormulaMapEntry( const ::css::table::CellAddress& rAddress,
+ const ::css::table::CellRangeAddress& rRange,
+ sal_Int32 nSharedId, const OUString& rTokens );
+
+ /// ensure sizes of vectors matches the number of sheets
+ void SetSheetCount( SCTAB nSheets );
};
+
}}
#endif
diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index cb427f2dd97a..9f4404b3d6c1 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -335,6 +335,15 @@ FormulaBuffer::FormulaBuffer( const WorkbookHelper& rHelper ) : WorkbookHelper(
{
}
+void FormulaBuffer::SetSheetCount( SCTAB nSheets )
+{
+ maCellFormulas.resize( nSheets );
+ maCellArrayFormulas.resize( nSheets );
+ maSharedFormulas.resize( nSheets );
+ maSharedFormulaIds.resize( nSheets );
+ maCellFormulaValues.resize( nSheets );
+}
+
void FormulaBuffer::finalizeImport()
{
ISegmentProgressBarRef xFormulaBar = getProgressBar().createSegment( getProgressBar().getFreeLength() );
@@ -401,35 +410,24 @@ FormulaBuffer::SheetItem FormulaBuffer::getSheetItem( SCTAB nTab )
osl::MutexGuard aGuard(&maMtxData);
SheetItem aItem;
- {
- FormulaDataMap::iterator it = maCellFormulas.find(nTab);
- if (it != maCellFormulas.end())
- aItem.mpCellFormulas = &it->second;
- }
-
- {
- ArrayFormulaDataMap::iterator it = maCellArrayFormulas.find(nTab);
- if (it != maCellArrayFormulas.end())
- aItem.mpArrayFormulas = &it->second;
- }
+ if( (size_t) nTab >= maCellFormulas.size() )
{
- FormulaValueMap::iterator it = maCellFormulaValues.find(nTab);
- if (it != maCellFormulaValues.end())
- aItem.mpCellFormulaValues = &it->second;
+ SAL_WARN( "sc", "Tab " << nTab << " out of bounds " << maCellFormulas.size() );
+ return aItem;
}
- {
- SheetToFormulaEntryMap::iterator it = maSharedFormulas.find(nTab);
- if (it != maSharedFormulas.end())
- aItem.mpSharedFormulaEntries = &it->second;
- }
+ if( maCellFormulas[ nTab ].size() > 0 )
+ aItem.mpCellFormulas = &maCellFormulas[ nTab ];
+ if( maCellArrayFormulas[ nTab ].size() > 0 )
+ aItem.mpArrayFormulas = &maCellArrayFormulas[ nTab ];
+ if( maCellFormulaValues[ nTab ].size() > 0 )
+ aItem.mpCellFormulaValues = &maCellFormulaValues[ nTab ];
+ if( maSharedFormulas[ nTab ].size() > 0 )
+ aItem.mpSharedFormulaEntries = &maSharedFormulas[ nTab ];
+ if( maSharedFormulaIds[ nTab ].size() > 0 )
+ aItem.mpSharedFormulaIDs = &maSharedFormulaIds[ nTab ];
- {
- SheetToSharedFormulaid::iterator it = maSharedFormulaIds.find(nTab);
- if (it != maSharedFormulaIds.end())
- aItem.mpSharedFormulaIDs = &it->second;
- }
return aItem;
}
@@ -437,6 +435,7 @@ void FormulaBuffer::createSharedFormulaMapEntry(
const table::CellAddress& rAddress, const table::CellRangeAddress& rRange,
sal_Int32 nSharedId, const OUString& rTokens )
{
+ assert( rAddress.Sheet >= 0 && (size_t)rAddress.Sheet < maSharedFormulas.size() );
std::vector<SharedFormulaEntry>& rSharedFormulas = maSharedFormulas[ rAddress.Sheet ];
SharedFormulaEntry aEntry(rAddress, rRange, rTokens, nSharedId);
rSharedFormulas.push_back( aEntry );
@@ -444,12 +443,14 @@ void FormulaBuffer::createSharedFormulaMapEntry(
void FormulaBuffer::setCellFormula( const ::com::sun::star::table::CellAddress& rAddress, const OUString& rTokenStr )
{
+ assert( rAddress.Sheet >= 0 && (size_t)rAddress.Sheet < maCellFormulas.size() );
maCellFormulas[ rAddress.Sheet ].push_back( TokenAddressItem( rTokenStr, rAddress ) );
}
void FormulaBuffer::setCellFormula(
const table::CellAddress& rAddress, sal_Int32 nSharedId, const OUString& rCellValue, sal_Int32 nValueType )
{
+ assert( rAddress.Sheet >= 0 && (size_t)rAddress.Sheet < maSharedFormulaIds.size() );
maSharedFormulaIds[rAddress.Sheet].push_back(
SharedFormulaDesc(rAddress, nSharedId, rCellValue, nValueType));
}
@@ -458,11 +459,13 @@ void FormulaBuffer::setCellArrayFormula( const ::com::sun::star::table::CellRang
{
TokenAddressItem tokenPair( rTokenStr, rTokenAddress );
+ assert( rRangeAddress.Sheet >= 0 && (size_t)rRangeAddress.Sheet < maCellArrayFormulas.size() );
maCellArrayFormulas[ rRangeAddress.Sheet ].push_back( TokenRangeAddressItem( tokenPair, rRangeAddress ) );
}
void FormulaBuffer::setCellFormulaValue( const ::com::sun::star::table::CellAddress& rAddress, double fValue )
{
+ assert( rAddress.Sheet >= 0 && (size_t)rAddress.Sheet < maCellFormulaValues.size() );
maCellFormulaValues[ rAddress.Sheet ].push_back( ValueAddressPair( rAddress, fValue ) );
}
diff --git a/sc/source/filter/oox/workbookfragment.cxx b/sc/source/filter/oox/workbookfragment.cxx
index bfc5e7bc7bfb..23c4552159bd 100644
--- a/sc/source/filter/oox/workbookfragment.cxx
+++ b/sc/source/filter/oox/workbookfragment.cxx
@@ -32,6 +32,7 @@
#include "connectionsfragment.hxx"
#include "externallinkbuffer.hxx"
#include "externallinkfragment.hxx"
+#include "formulabuffer.hxx"
#include "pivotcachebuffer.hxx"
#include "sharedstringsbuffer.hxx"
#include "sharedstringsfragment.hxx"
@@ -297,7 +298,7 @@ public:
}
};
-void importSheetFragments( WorkbookFragment& rWorkbookHandler, SheetFragmentVector& rSheets )
+static void importSheetFragments( WorkbookFragment& rWorkbookHandler, SheetFragmentVector& rSheets )
{
sal_Int32 nThreads = std::min( rSheets.size(), (size_t) 4 /* FIXME: ncpus/2 */ );
@@ -455,6 +456,9 @@ void WorkbookFragment::finalizeImport()
}
}
+ // setup structure sizes for the number of sheets
+ getFormulaBuffer().SetSheetCount( aSheetFragments.size() );
+
// create all defined names and database ranges
getDefinedNames().finalizeImport();
getTables().finalizeImport();