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.deshm...@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;
 
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to