From 4d6b88417fe01a8e4039d495071cd817b4efcc3a Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Wed, 7 Dec 2011 16:59:10 -0500 Subject: fdo#42259: Fixed RTF import crash etc. This is also another unfortunate bug due to the logic change caused by the DECLARE_LIST removal. There was one crasher due to out-of-bound array access, plus one incorrect behavior concerning cell content placement. Both are now fixed. --- sc/source/filter/inc/rtfparse.hxx | 7 +++-- sc/source/filter/rtf/rtfparse.cxx | 56 ++++++++++++++++++++------------------- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/sc/source/filter/inc/rtfparse.hxx b/sc/source/filter/inc/rtfparse.hxx index 021a0b585262..77c82bb788ce 100644 --- a/sc/source/filter/inc/rtfparse.hxx +++ b/sc/source/filter/inc/rtfparse.hxx @@ -44,7 +44,6 @@ struct ScRTFCellDefault ScRTFCellDefault( SfxItemPool* pPool ) : aItemSet( *pPool ), nColOverlap(1) {} }; -typedef boost::ptr_vector< ScRTFCellDefault > ScRTFDefaultList; // deswegen ULONG, typedef bringt's auch nicht :-( SV_DECL_VARARR_SORT( ScRTFColTwips, sal_uLong, 16, 4) @@ -63,7 +62,11 @@ class EditEngine; class ScRTFParser : public ScEEParser { private: - ScRTFDefaultList* pDefaultList; + typedef boost::ptr_vector DefaultList; + + DefaultList maDefaultList; + size_t mnCurPos; + ScRTFColTwips* pColTwips; ScRTFCellDefault* pInsDefault; ScRTFCellDefault* pActDefault; diff --git a/sc/source/filter/rtf/rtfparse.cxx b/sc/source/filter/rtf/rtfparse.cxx index e2dc861a1043..4a483c465d6c 100644 --- a/sc/source/filter/rtf/rtfparse.cxx +++ b/sc/source/filter/rtf/rtfparse.cxx @@ -57,7 +57,7 @@ SV_IMPL_VARARR_SORT( ScRTFColTwips, sal_uLong ); ScRTFParser::ScRTFParser( EditEngine* pEditP ) : ScEEParser( pEditP ), - pDefaultList( new ScRTFDefaultList ), + mnCurPos(0), pColTwips( new ScRTFColTwips ), pActDefault( NULL ), pDefMerge( NULL ), @@ -77,8 +77,7 @@ ScRTFParser::~ScRTFParser() { delete pInsDefault; delete pColTwips; - pDefaultList->clear(); - delete pDefaultList; + maDefaultList.clear(); } @@ -234,17 +233,16 @@ void ScRTFParser::NewCellRow( ImportInfo* /*pInfo*/ ) { if ( bNewDef ) { - ScRTFCellDefault* pD; bNewDef = false; // rechts nicht buendig? => neue Tabelle - if ( nLastWidth && !pDefaultList->empty() ) + if ( nLastWidth && !maDefaultList.empty() ) { - pD = &(pDefaultList->back()); - if (pD->nTwips != nLastWidth ) + const ScRTFCellDefault& rD = maDefaultList.back(); + if (rD.nTwips != nLastWidth) { SCCOL n1, n2; if ( !( SeekTwips( nLastWidth, &n1 ) - && SeekTwips( pD->nTwips, &n2 ) + && SeekTwips( rD.nTwips, &n2 ) && n1 == n2 ) ) @@ -254,16 +252,17 @@ void ScRTFParser::NewCellRow( ImportInfo* /*pInfo*/ ) } } // TwipCols aufbauen, erst nach nLastWidth Vergleich! - for ( size_t i = 0, nListSize = pDefaultList->size(); i < nListSize; ++i ) + for ( size_t i = 0, n = maDefaultList.size(); i < n; ++i ) { - pD = &( pDefaultList->at( i ) ); - SCCOL n; - if ( !SeekTwips( pD->nTwips, &n ) ) - pColTwips->Insert( pD->nTwips ); + const ScRTFCellDefault& rD = maDefaultList[i]; + SCCOL nCol; + if ( !SeekTwips(rD.nTwips, &nCol) ) + pColTwips->Insert( rD.nTwips ); } } pDefMerge = NULL; - pActDefault = &(pDefaultList->front()); + pActDefault = maDefaultList.empty() ? NULL : &maDefaultList[0]; + mnCurPos = 0; OSL_ENSURE( pActDefault, "NewCellRow: pActDefault==0" ); } @@ -297,18 +296,19 @@ void ScRTFParser::NewCellRow( ImportInfo* /*pInfo*/ ) void ScRTFParser::ProcToken( ImportInfo* pInfo ) { - ScRTFCellDefault* pD; ScEEParseEntry* pE; switch ( pInfo->nToken ) { case RTF_TROWD: // denotes table row defauls, before RTF_CELLX { - if ( !pDefaultList->empty() && (pD = &(pDefaultList->back())) != 0 ) - nLastWidth = pD->nTwips; + if (!maDefaultList.empty()) + nLastWidth = maDefaultList.back().nTwips; + nColCnt = 0; - pDefaultList->clear(); + maDefaultList.clear(); pDefMerge = NULL; nLastToken = pInfo->nToken; + mnCurPos = 0; } break; case RTF_CLMGF: // The first cell of cells to be merged @@ -319,10 +319,11 @@ void ScRTFParser::ProcToken( ImportInfo* pInfo ) break; case RTF_CLMRG: // A cell to be merged with the preceding cell { - if ( !pDefMerge - && !(pDefaultList->empty()) - ) - pDefMerge = &( pDefaultList->back() ); + if (!pDefMerge && !maDefaultList.empty()) + { + pDefMerge = &maDefaultList.back(); + mnCurPos = maDefaultList.size() - 1; + } OSL_ENSURE( pDefMerge, "RTF_CLMRG: pDefMerge==0" ); if ( pDefMerge ) // sonst rottes RTF pDefMerge->nColOverlap++; // mehrere nacheinander moeglich @@ -335,7 +336,7 @@ void ScRTFParser::ProcToken( ImportInfo* pInfo ) bNewDef = sal_True; pInsDefault->nCol = nColCnt; pInsDefault->nTwips = pInfo->nTokenValue; // rechter Zellenrand - pDefaultList->push_back( pInsDefault ); + maDefaultList.push_back( pInsDefault ); // neuer freifliegender pInsDefault pInsDefault = new ScRTFCellDefault( pPool ); if ( ++nColCnt > nColMax ) @@ -387,10 +388,11 @@ void ScRTFParser::ProcToken( ImportInfo* pInfo ) // Paragraph -1 wg. Textaufbruch in EditEngine waehrend Parse pActEntry->aSel.nStartPara = pInfo->aSelection.nEndPara - 1; } - if ( pDefaultList->empty() ) - pActDefault = NULL; - else - pActDefault = &( pDefaultList->back() ); + + pActDefault = NULL; + if (!maDefaultList.empty() && (mnCurPos+1) < maDefaultList.size()) + pActDefault = &maDefaultList[++mnCurPos]; + nLastToken = pInfo->nToken; } break; -- cgit v1.2.3