summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorRohit Deshmukh <rohit.deshmukh@synerzip.com>2013-11-21 11:17:40 +0530
committerMiklos Vajna <vmiklos@collabora.co.uk>2013-12-13 13:49:14 +0100
commit29c079f0480f63dd3f046f30c2b81023c2a5aebf (patch)
tree7b5d48da27c7db6d2abac7d122be8c214b4be21d /sw
parent0b9644e2443879e825fc72d5faf55080888a91b8 (diff)
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
Diffstat (limited to 'sw')
-rw-r--r--sw/qa/extras/ooxmlexport/data/testCrashWhileSave.docxbin0 -> 40873 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport.cxx8
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx82
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.hxx30
-rw-r--r--sw/source/filter/ww8/docxexport.cxx6
-rw-r--r--sw/source/filter/ww8/docxexport.hxx3
6 files changed, 98 insertions, 31 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/testCrashWhileSave.docx b/sw/qa/extras/ooxmlexport/data/testCrashWhileSave.docx
new file mode 100644
index 000000000000..205995171119
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/testCrashWhileSave.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index d5946273dd8f..7428200b14f7 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 68967175dc85..2d938b57c45d 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 958300dec491..3ef815abbfa6 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 2edcf5654db8..2409e425ad94 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 cac754e0539c..5dd9e04b9f1b 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;