[Libreoffice-commits] core.git: sw/qa sw/source
Rohit Deshmukh
rohit.deshmukh at synerzip.com
Fri Dec 13 04:49:38 PST 2013
sw/qa/extras/ooxmlexport/data/testCrashWhileSave.docx |binary
sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 8 +
sw/source/filter/ww8/docxattributeoutput.cxx | 82 ++++++++++++------
sw/source/filter/ww8/docxattributeoutput.hxx | 30 +++++-
sw/source/filter/ww8/docxexport.cxx | 6 -
sw/source/filter/ww8/docxexport.hxx | 3
6 files changed, 98 insertions(+), 31 deletions(-)
New commits:
commit 29c079f0480f63dd3f046f30c2b81023c2a5aebf
Author: Rohit Deshmukh <rohit.deshmukh at synerzip.com>
Date: Thu Nov 21 11:17:40 2013 +0530
fdo#71594: Fix for LO crash while saving of file.
1] Libreoffice gets crashed while saving.
2] This caused:
"testCrashWhileSave.docx" file crashes on save
Tested on Libreoffice 4.2
Implementation:
1] It crashes when we are trying to access cell number 2 from
cells vector which contains only single cell. So put check
for cell number which we are accessing and Number of cells
in single row.
2] As we are exporting Header and footer in between when we are
exporting document.xml. In this case we are facing issue in
table export for header and footer. Because flags for table
is getting shared in both export.
So we are switching between flags in between exporting
"document.xml" and Header & footer
export.
After fix:
1] No crash on save for "testCrashWhileSave.docx" and
opens successfully on MS Office 2010
Added Unit test case in export.
Conflicts:
sw/qa/extras/ooxmlexport/ooxmlexport.cxx
Reviewed on:
https://gerrit.libreoffice.org/6676
Change-Id: Iefbf565f7b512d76ac68e9353e225edca425ef06
diff --git a/sw/qa/extras/ooxmlexport/data/testCrashWhileSave.docx b/sw/qa/extras/ooxmlexport/data/testCrashWhileSave.docx
new file mode 100644
index 0000000..2059951
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/testCrashWhileSave.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index d594627..7428200 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -2128,6 +2128,14 @@ DECLARE_OOXMLEXPORT_TEST(testFdo71785, "fdo71785.docx")
// crashtest
}
+DECLARE_OOXMLEXPORT_TEST(testCrashWhileSave, "testCrashWhileSave.docx")
+{
+ xmlDocPtr pXmlDoc = parseExport("word/footer1.xml");
+ if (!pXmlDoc)
+ return;
+ CPPUNIT_ASSERT(getXPath(pXmlDoc, "/w:ftr/w:tbl/w:tr/w:tc[1]/w:p[1]/w:pPr/w:pStyle", "val").match("Normal"));
+}
+
#endif
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 6896717..2d938b5 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -237,9 +237,9 @@ void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pText
sal_uInt32 nCell = pTextNodeInfo->getCell();
// New cell/row?
- if ( m_nTableDepth > 0 && !m_bTableCellOpen )
+ if ( m_tableReference->m_nTableDepth > 0 && !m_tableReference->m_bTableCellOpen )
{
- ww8::WW8TableNodeInfoInner::Pointer_t pDeepInner( pTextNodeInfo->getInnerForDepth( m_nTableDepth ) );
+ ww8::WW8TableNodeInfoInner::Pointer_t pDeepInner( pTextNodeInfo->getInnerForDepth( m_tableReference->m_nTableDepth ) );
if ( pDeepInner->getCell() == 0 )
StartTableRow( pDeepInner );
@@ -253,10 +253,10 @@ void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pText
// continue the table cell]
sal_uInt32 nCurrentDepth = pTextNodeInfo->getDepth();
- if ( nCurrentDepth > m_nTableDepth )
+ if ( nCurrentDepth > m_tableReference->m_nTableDepth )
{
// Start all the tables that begin here
- for ( sal_uInt32 nDepth = m_nTableDepth + 1; nDepth <= pTextNodeInfo->getDepth(); ++nDepth )
+ for ( sal_uInt32 nDepth = m_tableReference->m_nTableDepth + 1; nDepth <= pTextNodeInfo->getDepth(); ++nDepth )
{
ww8::WW8TableNodeInfoInner::Pointer_t pInner( pTextNodeInfo->getInnerForDepth( nDepth ) );
@@ -265,7 +265,7 @@ void DocxAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pText
StartTableCell( pInner );
}
- m_nTableDepth = nCurrentDepth;
+ m_tableReference->m_nTableDepth = nCurrentDepth;
}
}
}
@@ -2014,13 +2014,18 @@ void DocxAttributeOutput::TableCellProperties( ww8::WW8TableNodeInfoInner::Point
// Horizontal spans
const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
- const SwWriteTableCell *pCell = &pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
+ sal_uInt32 nCell = pTableTextNodeInfoInner->getCell();
+ const SwWriteTableCells *tableCells = &pRow->GetCells();
+ if (nCell < tableCells->size() )
+ {
+ const SwWriteTableCell *pCell = &pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
- sal_uInt16 nColSpan = pCell->GetColSpan();
- if ( nColSpan > 1 )
- m_pSerializer->singleElementNS( XML_w, XML_gridSpan,
- FSNS( XML_w, XML_val ), OString::number( nColSpan ).getStr(),
- FSEND );
+ sal_uInt16 nColSpan = pCell->GetColSpan();
+ if ( nColSpan > 1 )
+ m_pSerializer->singleElementNS( XML_w, XML_gridSpan,
+ FSNS( XML_w, XML_val ), OString::number( nColSpan ).getStr(),
+ FSEND );
+ }
// Vertical merges
long vSpan = pTblBox->getRowSpan( );
@@ -2076,6 +2081,32 @@ void DocxAttributeOutput::InitTableHelper( ww8::WW8TableNodeInfoInner::Pointer_t
(sal_uInt16)nTblSz, false);
}
+/**
+ * As we are exporting Header and footer in between when we are exporting document.xml.
+ * In this case we are facing issue in table export for header and footer. Because
+ * flags for table is getting shared in both export.
+ * So we are switching between flags in between exporting "document.xml" and Header & footer
+ * export.
+ */
+void DocxAttributeOutput::switchHeaderFooter(bool isHeaderFooter, sal_Int32 index)
+{
+ if( isHeaderFooter && index == 1)
+ {
+ m_oldTableReference->m_bTableCellOpen = m_tableReference->m_bTableCellOpen;
+ m_oldTableReference->m_nTableDepth = m_tableReference->m_nTableDepth;
+ m_tableReference->m_bTableCellOpen = false;
+ m_tableReference->m_nTableDepth = 0;
+ }
+ else if( index == -1)
+ {
+ m_tableReference = m_oldTableReference;
+ }
+ else
+ {
+ m_tableReference->m_bTableCellOpen = false;
+ m_tableReference->m_nTableDepth = 0;
+ }
+}
void DocxAttributeOutput::StartTable( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )
{
m_pSerializer->startElementNS( XML_w, XML_tbl, FSEND );
@@ -2090,14 +2121,14 @@ void DocxAttributeOutput::EndTable()
{
m_pSerializer->endElementNS( XML_w, XML_tbl );
- if ( m_nTableDepth > 0 )
- --m_nTableDepth;
+ if ( m_tableReference->m_nTableDepth > 0 )
+ --m_tableReference->m_nTableDepth;
tableFirstCells.pop_back();
// We closed the table; if it is a nested table, the cell that contains it
// still continues
- m_bTableCellOpen = true;
+ m_tableReference->m_bTableCellOpen = true;
// Cleans the table helper
delete m_pTableWrt, m_pTableWrt = NULL;
@@ -2138,7 +2169,7 @@ void DocxAttributeOutput::StartTableCell( ww8::WW8TableNodeInfoInner::Pointer_t
// Write the cell properties here
TableCellProperties( pTableTextNodeInfoInner );
- m_bTableCellOpen = true;
+ m_tableReference->m_bTableCellOpen = true;
}
void DocxAttributeOutput::EndTableCell( )
@@ -2146,7 +2177,7 @@ void DocxAttributeOutput::EndTableCell( )
m_pSerializer->endElementNS( XML_w, XML_tc );
m_bBtLr = false;
- m_bTableCellOpen = false;
+ m_tableReference->m_bTableCellOpen = false;
}
void DocxAttributeOutput::TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t /*pTableTextNodeInfoInner*/ )
@@ -2235,7 +2266,7 @@ void DocxAttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t
// If nested, tblInd is added to parent table's left spacing and defines left edge position
// If not nested, text position of left-most cell must be at absolute X = tblInd
// so, table_spacing + table_spacing_to_content = tblInd
- if (m_nTableDepth == 0)
+ if (m_tableReference->m_nTableDepth == 0)
{
const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox();
const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt();
@@ -2410,19 +2441,24 @@ void DocxAttributeOutput::TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer
const SwWriteTableRows& aRows = m_pTableWrt->GetRows( );
SwWriteTableRow *pRow = aRows[ pTableTextNodeInfoInner->getRow( ) ];
- const SwWriteTableCell *pCell = &pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
- switch( pCell->GetVertOri())
+ sal_uInt32 nCell = pTableTextNodeInfoInner->getCell();
+ const SwWriteTableCells *tableCells = &pRow->GetCells();
+ if (nCell < tableCells->size() )
{
+ const SwWriteTableCell *pCell = &pRow->GetCells( )[ pTableTextNodeInfoInner->getCell( ) ];
+ switch( pCell->GetVertOri())
+ {
case text::VertOrientation::TOP:
break;
case text::VertOrientation::CENTER:
m_pSerializer->singleElementNS( XML_w, XML_vAlign,
- FSNS( XML_w, XML_val ), "center", FSEND );
+ FSNS( XML_w, XML_val ), "center", FSEND );
break;
case text::VertOrientation::BOTTOM:
m_pSerializer->singleElementNS( XML_w, XML_vAlign,
- FSNS( XML_w, XML_val ), "bottom", FSEND );
+ FSNS( XML_w, XML_val ), "bottom", FSEND );
break;
+ }
}
}
@@ -6570,8 +6606,6 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSeri
m_bPostitStart(false),
m_bPostitEnd(false),
m_pTableWrt( NULL ),
- m_bTableCellOpen( false ),
- m_nTableDepth( 0 ),
m_bParagraphOpened( false ),
m_nColBreakStatus( COLBRK_NONE ),
m_bTextFrameSyntax( false ),
@@ -6589,6 +6623,8 @@ DocxAttributeOutput::DocxAttributeOutput( DocxExport &rExport, FSHelperPtr pSeri
m_postitFieldsMaxId( 0 ),
m_anchorId( 1 ),
m_nextFontId( 1 ),
+ m_tableReference(new TableReference()),
+ m_oldTableReference(new TableReference()),
m_bBtLr(false),
m_bFrameBtLr(false),
m_pTableStyleExport(new DocxTableStyleExport(rExport.pDoc, pSerializer)),
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 958300d..3ef815a 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -100,6 +100,24 @@ struct PageMargins
PageMargins() : nPageMarginLeft(0), nPageMarginRight(0), nPageMarginTop(0), nPageMarginBottom(0) {}
};
+/**
+ * A structure that holds flags for the table export.
+ */
+struct TableReference
+{
+ /// Remember if we are in an open cell, or not.
+ bool m_bTableCellOpen;
+
+ /// Remember the current table depth.
+ sal_uInt32 m_nTableDepth;
+
+ TableReference()
+ : m_bTableCellOpen(false),
+ m_nTableDepth(0)
+ {
+ }
+};
+
/// The class that has handlers for various resource types when exporting as DOCX.
class DocxAttributeOutput : public AttributeOutputBase, public oox::vml::VMLTextExport, public oox::drawingml::DMLTextExport
{
@@ -721,12 +739,6 @@ private:
/// The current table helper
SwWriteTable *m_pTableWrt;
- /// Remember if we are in an open cell, or not.
- bool m_bTableCellOpen;
-
- /// Remember the current table depth.
- sal_uInt32 m_nTableDepth;
-
bool m_bParagraphOpened;
// Remember that a column break has to be opened at the
@@ -781,6 +793,11 @@ private:
OString relId;
OString fontKey;
};
+
+
+ TableReference *m_tableReference;
+ TableReference *m_oldTableReference;
+
std::map< OUString, EmbeddedFontRef > fontFilesMap; // font file url to data
// Remember first cell (used for for default borders/margins) of each table
@@ -836,6 +853,7 @@ public:
/// VMLTextExport
virtual void WriteOutliner(const OutlinerParaObject& rParaObj);
virtual oox::drawingml::DrawingML& GetDrawingML();
+ virtual void switchHeaderFooter(bool isHeaderFooter, sal_Int32 index);
void BulletDefinition(int nId, const Graphic& rGraphic, Size aSize) SAL_OVERRIDE;
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx
index 2edcf56..2409e42 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -201,6 +201,7 @@ bool DocxExport::DisallowInheritingOutlineNumbering( const SwFmt& rFmt )
void DocxExport::WriteHeadersFooters( sal_uInt8 nHeadFootFlags,
const SwFrmFmt& rFmt, const SwFrmFmt& rLeftFmt, const SwFrmFmt& rFirstPageFmt, sal_uInt8 /*nBreakCode*/ )
{
+ m_nHeadersFootersInSection = 1;
// Turn ON flag for 'Writing Headers \ Footers'
m_pAttrOutput->SetWritingHeaderFooter( true );
@@ -229,7 +230,7 @@ void DocxExport::WriteHeadersFooters( sal_uInt8 nHeadFootFlags,
// Turn OFF flag for 'Writing Headers \ Footers'
m_pAttrOutput->SetWritingHeaderFooter( false );
-
+ m_pAttrOutput->switchHeaderFooter(false, -1);
#if OSL_DEBUG_LEVEL > 1
fprintf( stderr, "DocxExport::WriteHeadersFooters() - nBreakCode introduced, but ignored\n" );
#endif
@@ -628,7 +629,7 @@ void DocxExport::WriteHeaderFooter( const SwFmt& rFmt, bool bHeader, const char*
// switch the serializer to redirect the output to word/styles.xml
m_pAttrOutput->SetSerializer( pFS );
m_pVMLExport->SetFS( pFS );
-
+ m_pAttrOutput->switchHeaderFooter(true, m_nHeadersFootersInSection++);
// do the work
WriteHeaderFooterText( rFmt, bHeader );
@@ -1199,6 +1200,7 @@ DocxExport::DocxExport( DocxExportFilter *pFilter, SwDoc *pDocument, SwPaM *pCur
m_pSections( NULL ),
m_nHeaders( 0 ),
m_nFooters( 0 ),
+ m_nHeadersFootersInSection(0),
m_pVMLExport( NULL )
{
// Write the document properies
diff --git a/sw/source/filter/ww8/docxexport.hxx b/sw/source/filter/ww8/docxexport.hxx
index cac754e..5dd9e04 100644
--- a/sw/source/filter/ww8/docxexport.hxx
+++ b/sw/source/filter/ww8/docxexport.hxx
@@ -83,6 +83,9 @@ class DocxExport : public MSWordExportBase
/// Footer counter.
sal_Int32 m_nFooters;
+ ///Footer and Header counter in Section properties
+ sal_Int32 m_nHeadersFootersInSection;
+
/// Exporter of the VML shapes.
oox::vml::VMLExport *m_pVMLExport;
More information about the Libreoffice-commits
mailing list