[Libreoffice-commits] core.git: Branch 'libreoffice-4-2' - sw/qa writerfilter/source

Miklos Vajna vmiklos at collabora.co.uk
Mon Apr 7 03:33:05 PDT 2014


 sw/qa/extras/rtfimport/data/fdo74823.rtf       |   32 +++++++++++++++
 sw/qa/extras/rtfimport/rtfimport.cxx           |   10 ++++
 writerfilter/source/rtftok/rtfdocumentimpl.cxx |   53 +++++++++++++++++++++----
 writerfilter/source/rtftok/rtfdocumentimpl.hxx |    8 +++
 4 files changed, 96 insertions(+), 7 deletions(-)

New commits:
commit 66e8622c794548db27cee3180c228cf287248154
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Sat Apr 5 15:38:18 2014 +0200

    fdo#74823 RTF import: work around wrong table column width on invalid input
    
    This scenario is not a valid one, Word doesn't handle it, either -- but
    the old LO 3.4 parser did. So add minimal support for it to avoid
    the regression.
    
    (cherry picked from commit 0a215b9a980e68f899ad548f780bbe5a1fec8732)
    
    Conflicts:
    	sw/qa/extras/rtfimport/rtfimport.cxx
    
    Change-Id: Icc2e8d3bf314e9cadda57956668033aa6d092457
    Reviewed-on: https://gerrit.libreoffice.org/8871
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sw/qa/extras/rtfimport/data/fdo74823.rtf b/sw/qa/extras/rtfimport/data/fdo74823.rtf
new file mode 100644
index 0000000..709e375
--- /dev/null
+++ b/sw/qa/extras/rtfimport/data/fdo74823.rtf
@@ -0,0 +1,32 @@
+{\rtf1
+\cellx2500
+\cellx5000
+\cellx5500
+\cellx6000
+\cellx6500
+\cellx7000
+\cellx10200
+\intbl
+A1\cell
+B1\cell
+C1\cell
+D1\cell
+E1\cell
+F1\cell
+G1\cell
+\trowd
+\row
+\cellx2500
+\cellx5000
+\cellx5500
+\cellx6000
+\cellx6500
+\cellx7000
+\cellx10200
+\intbl
+A2\cell
+\trowd
+\intbl
+\cell C2\cell\cell\cell\cell\cell \par\row
+\pard\plain \par
+}
diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx
index 8d24829..7961519 100644
--- a/sw/qa/extras/rtfimport/rtfimport.cxx
+++ b/sw/qa/extras/rtfimport/rtfimport.cxx
@@ -1605,6 +1605,16 @@ DECLARE_RTFIMPORT_TEST(testDprectAnchor, "dprect-anchor.rtf")
     CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER, getProperty<text::TextContentAnchorType>(getShape(1), "AnchorType"));
 }
 
+DECLARE_RTFIMPORT_TEST(testFdo74823, "fdo74823.rtf")
+{
+    uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
+    uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
+    // Cell width of C2 was too large / column separator being 3749 too small (e.g. not set, around 3/7 of total width)
+    uno::Reference<table::XTableRows> xTableRows(xTable->getRows(), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(5391), getProperty< uno::Sequence<text::TableColumnSeparator> >(xTableRows->getByIndex(1), "TableColumnSeparators")[2].Position);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 5078491..4bf522f 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -255,6 +255,7 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x
     m_nInheritingCells(0),
     m_nNestedCurrentCellX(0),
     m_nTopLevelCurrentCellX(0),
+    m_nBackupTopLevelCurrentCellX(0),
     m_aTableBufferStack(1), // create top-level buffer already
     m_aSuperBuffer(),
     m_bHasFootnote(false),
@@ -2050,6 +2051,15 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
             break;
         case RTF_ROW:
             {
+                bool bRestored = false;
+                // Ending a row, but no cells defined?
+                // See if there was an invalid table row reset, so we can restore cell infos to help invalid documents.
+                if (!m_nTopLevelCurrentCellX && m_nBackupTopLevelCurrentCellX)
+                {
+                    restoreTableRowProperties();
+                    bRestored = true;
+                }
+
                 // If the right edge of the last cell (row width) is smaller than the width of some other row, mimic WW8TabDesc::CalcDefaults(): add a fake cell.
                 const int MINLAY = 23; // sw/inc/swtypes.hxx, minimal possible size of frames.
                 if ((m_nCellxMax - m_nTopLevelCurrentCellX) >= MINLAY)
@@ -2104,6 +2114,11 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
                 m_bNeedFinalPar = true;
                 m_aTableBufferStack.back().clear();
                 m_nTopLevelCells = 0;
+
+                if (bRestored)
+                    // We restored cell definitions, clear these now.
+                    // This is necessary, as later cell definitions want to overwrite the restored ones.
+                    resetTableRowProperties();
             }
             break;
         case RTF_COLUMN:
@@ -2196,6 +2211,34 @@ bool lcl_findPropertyName(const std::vector<beans::PropertyValue>& rProperties,
     return false;
 }
 
+void RTFDocumentImpl::backupTableRowProperties()
+{
+    if (m_nTopLevelCurrentCellX)
+    {
+        m_aBackupTableRowSprms = m_aStates.top().aTableRowSprms;
+        m_aBackupTableRowAttributes = m_aStates.top().aTableRowAttributes;
+        m_nBackupTopLevelCurrentCellX = m_nTopLevelCurrentCellX;
+    }
+}
+
+void RTFDocumentImpl::restoreTableRowProperties()
+{
+    m_aStates.top().aTableRowSprms = m_aBackupTableRowSprms;
+    m_aStates.top().aTableRowAttributes = m_aBackupTableRowAttributes;
+    m_nTopLevelCurrentCellX = m_nBackupTopLevelCurrentCellX;
+}
+
+void RTFDocumentImpl::resetTableRowProperties()
+{
+    m_aStates.top().aTableRowSprms = m_aDefaultState.aTableRowSprms;
+    m_aStates.top().aTableRowSprms.set(NS_ooxml::LN_CT_TblGridBase_gridCol, RTFValue::Pointer_t(new RTFValue(-1)), false);
+    m_aStates.top().aTableRowAttributes = m_aDefaultState.aTableRowAttributes;
+    if (DESTINATION_NESTEDTABLEPROPERTIES == m_aStates.top().nDestinationState)
+        m_nNestedCurrentCellX = 0;
+    else
+        m_nTopLevelCurrentCellX = 0;
+}
+
 int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
 {
     setNeedSect();
@@ -2488,13 +2531,9 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
             break;
         case RTF_TROWD:
             {
-                m_aStates.top().aTableRowSprms = m_aDefaultState.aTableRowSprms;
-                m_aStates.top().aTableRowSprms.set(NS_ooxml::LN_CT_TblGridBase_gridCol, RTFValue::Pointer_t(new RTFValue(-1)), false);
-                m_aStates.top().aTableRowAttributes = m_aDefaultState.aTableRowAttributes;
-                if (DESTINATION_NESTEDTABLEPROPERTIES == m_aStates.top().nDestinationState)
-                    m_nNestedCurrentCellX = 0;
-                else
-                    m_nTopLevelCurrentCellX = 0;
+                // Back these up, in case later we still need this info.
+                backupTableRowProperties();
+                resetTableRowProperties();
                 // In case the table definition is in the middle of the row
                 // (invalid), make sure table definition is emitted.
                 m_bNeedPap = true;
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index fa1f3d6..8c8edcf 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -404,6 +404,9 @@ namespace writerfilter {
                 void checkUnicode(bool bUnicode, bool bHex);
                 /// If we need a final section break at the end of the document.
                 void setNeedSect(bool bNeedSect = true);
+                void resetTableRowProperties();
+                void backupTableRowProperties();
+                void restoreTableRowProperties();
 
                 uno::Reference<uno::XComponentContext> const& m_xContext;
                 uno::Reference<io::XInputStream> const& m_xInputStream;
@@ -467,6 +470,11 @@ namespace writerfilter {
                 /// Current cellx value (top-level table)
                 int m_nTopLevelCurrentCellX;
 
+                // Backup of what \trowd clears, to work around invalid input.
+                RTFSprms m_aBackupTableRowSprms;
+                RTFSprms m_aBackupTableRowAttributes;
+                int m_nBackupTopLevelCurrentCellX;
+
                 /// Buffered table cells, till cell definitions are not reached.
                 /// for nested table, one buffer per table level
                 std::deque< RTFBuffer_t > m_aTableBufferStack;


More information about the Libreoffice-commits mailing list