[Libreoffice-commits] core.git: 4 commits - sw/inc sw/source writerfilter/source

Michael Stahl mstahl at redhat.com
Thu Feb 28 05:09:05 PST 2013


 sw/inc/IDocumentMarkAccess.hxx                   |    8 +++
 sw/source/core/crsr/bookmrk.cxx                  |    7 +++
 sw/source/core/doc/docbm.cxx                     |   51 ++++++++++++++++-------
 sw/source/core/inc/MarkManager.hxx               |    3 -
 sw/source/core/inc/bookmrk.hxx                   |    5 +-
 sw/source/core/unocore/unoobj.cxx                |    5 ++
 writerfilter/source/dmapper/DomainMapper.cxx     |    7 ++-
 writerfilter/source/dmapper/NumberingManager.cxx |    8 +++
 8 files changed, 75 insertions(+), 19 deletions(-)

New commits:
commit 75b2f6b241046d4467a7c0c9cbf49b4533b46045
Author: Michael Stahl <mstahl at redhat.com>
Date:   Thu Feb 28 13:27:57 2013 +0100

    sw: remove CH_TXT_ATR_FORMELEMENT when CheckboxFieldmark is deleted
    
    Change-Id: I5f58b558b15f7d11b75554195e10a258d027bcfc

diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index 0cb1562..c9e572e 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -357,6 +357,13 @@ namespace sw { namespace mark
         // want this for checkboxes
         this->GetMarkEnd( ).nContent--;
     }
+
+    void CheckboxFieldmark::ReleaseDoc(SwDoc* const pDoc)
+    {
+        lcl_RemoveFieldMarks(this, pDoc,
+                CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FORMELEMENT);
+    }
+
     void CheckboxFieldmark::SetChecked(bool checked)
     {
         if ( IsChecked() != checked )
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index 4d06724..93c212d 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -670,18 +670,17 @@ namespace sw { namespace mark
 #endif
     }
 
-    struct LazyTextFieldmarkDeleter : public IDocumentMarkAccess::ILazyDeleter
+    struct LazyFieldmarkDeleter : public IDocumentMarkAccess::ILazyDeleter
     {
-        ::boost::shared_ptr<IMark> const m_pTextFieldmark;
+        ::boost::shared_ptr<IMark> const m_pFieldmark;
         SwDoc *const m_pDoc;
-        LazyTextFieldmarkDeleter(
+        LazyFieldmarkDeleter(
                 ::boost::shared_ptr<IMark> const& pMark, SwDoc *const pDoc)
-            : m_pTextFieldmark(pMark), m_pDoc(pDoc)
+            : m_pFieldmark(pMark), m_pDoc(pDoc)
         { }
-        virtual ~LazyTextFieldmarkDeleter()
+        virtual ~LazyFieldmarkDeleter()
         {
-            dynamic_cast<TextFieldmark*>(m_pTextFieldmark.get())
-                ->ReleaseDoc(m_pDoc);
+            dynamic_cast<Fieldmark *>(m_pFieldmark.get())->ReleaseDoc(m_pDoc);
         }
     };
 
@@ -713,12 +712,7 @@ namespace sw { namespace mark
                     "<MarkManager::deleteMark(..)>"
                     " - Bookmark not found.");
                 m_vFieldmarks.erase(ppFieldmark);
-                sw::mark::TextFieldmark* pTextFieldmark = dynamic_cast<sw::mark::TextFieldmark*>(ppMark->get());
-                if (pTextFieldmark)
-                {
-                    ret.reset(
-                        new LazyTextFieldmarkDeleter(*ppMark, m_pDoc));
-                }
+                ret.reset(new LazyFieldmarkDeleter(*ppMark, m_pDoc));
                 break;
             }
             case IDocumentMarkAccess::NAVIGATOR_REMINDER:
diff --git a/sw/source/core/inc/bookmrk.hxx b/sw/source/core/inc/bookmrk.hxx
index bab92bb..54dc972 100644
--- a/sw/source/core/inc/bookmrk.hxx
+++ b/sw/source/core/inc/bookmrk.hxx
@@ -213,6 +213,8 @@ namespace sw {
             virtual void SetFieldHelptext(const ::rtl::OUString& aFieldHelptext)
                 { m_aFieldHelptext = aFieldHelptext; }
 
+            virtual void ReleaseDoc(SwDoc* const) = 0;
+
             virtual void Invalidate();
             virtual rtl::OUString ToString() const;
 
@@ -228,7 +230,7 @@ namespace sw {
         public:
             TextFieldmark(const SwPaM& rPaM);
             virtual void InitDoc(SwDoc* const io_pDoc);
-            void ReleaseDoc(SwDoc* const pDoc);
+            virtual void ReleaseDoc(SwDoc* const pDoc);
         };
 
         class CheckboxFieldmark
@@ -238,6 +240,7 @@ namespace sw {
         public:
             CheckboxFieldmark(const SwPaM& rPaM);
             virtual void InitDoc(SwDoc* const io_pDoc);
+            virtual void ReleaseDoc(SwDoc* const pDoc);
             bool IsChecked() const;
             void SetChecked(bool checked);
 
commit 5bf6797e81d54177508d3eb370e8242e3b58a3f8
Author: Michael Stahl <mstahl at redhat.com>
Date:   Thu Feb 28 13:14:45 2013 +0100

    fdo#61016: sw::marks::MarkManager: delay deletion of text fieldmarks
    
    There is a STL assertion in deleteMarks because the ReleaseDoc call will
    recursively call into deleteMark again and delete marks that are in the
    vector vMarksToDelete up the stack.
    
    Change-Id: I9139b174f8a518a551a3ca8520396202c306abcf

diff --git a/sw/inc/IDocumentMarkAccess.hxx b/sw/inc/IDocumentMarkAccess.hxx
index 9b4bbb1..21e2d0c 100644
--- a/sw/inc/IDocumentMarkAccess.hxx
+++ b/sw/inc/IDocumentMarkAccess.hxx
@@ -57,6 +57,11 @@ class IDocumentMarkAccess
         typedef container_t::const_iterator const_iterator_t;
         typedef container_t::const_reverse_iterator const_reverse_iterator_t;
 
+        /// To avoid recursive calls of deleteMark, the removal of dummy
+        /// characters of fieldmarks has to be delayed; this is the baseclass
+        /// that can be subclassed for that purpose.
+        struct ILazyDeleter { virtual ~ILazyDeleter() { } };
+
         /** Generates a new mark in the document for a certain selection.
 
            @param rPaM
@@ -168,7 +173,8 @@ class IDocumentMarkAccess
             @param ppMark
             [in] an iterator pointing to the Mark to be deleted.
         */
-        virtual void deleteMark(const IDocumentMarkAccess::const_iterator_t ppMark) =0;
+        virtual ::boost::shared_ptr<ILazyDeleter>
+            deleteMark(const IDocumentMarkAccess::const_iterator_t ppMark) =0;
 
         /** Deletes a mark.
 
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index e809b7c..4d06724 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -644,16 +644,24 @@ namespace sw { namespace mark
             }
         }
 
-        // we just remembered the iterators to delete, so we do not need to search
-        // for the boost::shared_ptr<> (the entry in m_vMarks) again
-        // reverse iteration, since erasing an entry invalidates iterators
-        // behind it (the iterators in vMarksToDelete are sorted)
-        for(vector<const_iterator_t>::reverse_iterator pppMark = vMarksToDelete.rbegin();
-            pppMark != vMarksToDelete.rend();
-            ++pppMark)
         {
-            deleteMark(*pppMark);
-        }
+            // fdo#61016 delay the deletion of the fieldmark characters
+            // to prevent that from deleting the marks on that position
+            // which would invalidate the iterators in vMarksToDelete
+            vector< ::boost::shared_ptr<ILazyDeleter> > vDelay;
+            vDelay.reserve(vMarksToDelete.size());
+            // we just remembered the iterators to delete, so we do not need to
+            // search for the boost::shared_ptr<> (the entry in m_vMarks) again.
+            // reverse iteration, since erasing an entry invalidates iterators
+            // behind it (the iterators in vMarksToDelete are sorted)
+            for (vector<const_iterator_t>::reverse_iterator pppMark
+                    = vMarksToDelete.rbegin();
+                pppMark != vMarksToDelete.rend();
+                ++pppMark)
+            {
+                vDelay.push_back(deleteMark(*pppMark));
+            }
+        } // scope to kill vDelay
         if(isSortingNeeded)
             sortMarks();
 #if 0
@@ -662,9 +670,26 @@ namespace sw { namespace mark
 #endif
     }
 
-    void MarkManager::deleteMark(const const_iterator_t ppMark)
+    struct LazyTextFieldmarkDeleter : public IDocumentMarkAccess::ILazyDeleter
+    {
+        ::boost::shared_ptr<IMark> const m_pTextFieldmark;
+        SwDoc *const m_pDoc;
+        LazyTextFieldmarkDeleter(
+                ::boost::shared_ptr<IMark> const& pMark, SwDoc *const pDoc)
+            : m_pTextFieldmark(pMark), m_pDoc(pDoc)
+        { }
+        virtual ~LazyTextFieldmarkDeleter()
+        {
+            dynamic_cast<TextFieldmark*>(m_pTextFieldmark.get())
+                ->ReleaseDoc(m_pDoc);
+        }
+    };
+
+    ::boost::shared_ptr<IDocumentMarkAccess::ILazyDeleter>
+        MarkManager::deleteMark(const const_iterator_t ppMark)
     {
-        if(ppMark == m_vMarks.end()) return;
+        ::boost::shared_ptr<ILazyDeleter> ret;
+        if (ppMark == m_vMarks.end()) return ret;
 
         switch(IDocumentMarkAccess::GetType(**ppMark))
         {
@@ -690,7 +715,10 @@ namespace sw { namespace mark
                 m_vFieldmarks.erase(ppFieldmark);
                 sw::mark::TextFieldmark* pTextFieldmark = dynamic_cast<sw::mark::TextFieldmark*>(ppMark->get());
                 if (pTextFieldmark)
-                    pTextFieldmark->ReleaseDoc(m_pDoc);
+                {
+                    ret.reset(
+                        new LazyTextFieldmarkDeleter(*ppMark, m_pDoc));
+                }
                 break;
             }
             case IDocumentMarkAccess::NAVIGATOR_REMINDER:
@@ -721,6 +749,7 @@ namespace sw { namespace mark
         pMark_t xHoldPastErase = *aI;
         m_aMarkNamesSet.erase(ppMark->get()->GetName());
         m_vMarks.erase(aI);
+        return ret;
     }
 
     void MarkManager::deleteMark(const IMark* const pMark)
diff --git a/sw/source/core/inc/MarkManager.hxx b/sw/source/core/inc/MarkManager.hxx
index 2f17661..cf19e60 100644
--- a/sw/source/core/inc/MarkManager.hxx
+++ b/sw/source/core/inc/MarkManager.hxx
@@ -55,7 +55,8 @@ namespace sw {
             virtual void deleteMarks(const SwNodeIndex& rStt, const SwNodeIndex& rEnd, ::std::vector< ::sw::mark::SaveBookmark>* pSaveBkmk, const SwIndex* pSttIdx, const SwIndex* pEndIdx);
 
             // deleters
-            virtual void deleteMark(const const_iterator_t ppMark);
+            virtual ::boost::shared_ptr<ILazyDeleter>
+                deleteMark(const const_iterator_t ppMark);
             virtual void deleteMark(const ::sw::mark::IMark* const pMark);
             virtual void clearAllMarks();
 
commit dbb74ee9950dc706ea4fde3397a4c1d19b172fa9
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed Feb 27 23:20:24 2013 +0100

    fdo#61000: writerfilter: filter out unsupported list tab stops
    
    Change-Id: Ic9d31eba84b1d8d9cf93d8289621a65d43521a8b

diff --git a/writerfilter/source/dmapper/NumberingManager.cxx b/writerfilter/source/dmapper/NumberingManager.cxx
index fa59bd2..38b1f07 100644
--- a/writerfilter/source/dmapper/NumberingManager.cxx
+++ b/writerfilter/source/dmapper/NumberingManager.cxx
@@ -135,7 +135,13 @@ void ListLevel::SetValue( Id nId, sal_Int32 nValue )
             m_nXChFollow = nValue;
         break;
         case NS_ooxml::LN_CT_TabStop_pos:
-            m_nTabstop = nValue;
+            if (nValue < 0)
+            {
+                SAL_INFO("writerfilter",
+                        "unsupported list tab stop position " << nValue);
+            }
+            else
+                m_nTabstop = nValue;
         break;
         default:
             OSL_FAIL( "this line should never be reached");
commit 0d4ee442f170eee4c35b9a1b1cb596f71d256b1e
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed Feb 27 22:24:36 2013 +0100

    fdo#61309: writerfilter: filter out enormous numbering levels
    
    Change-Id: Iafef1c2ca2ca072bd604946fbe19b6a24e323512

diff --git a/sw/source/core/unocore/unoobj.cxx b/sw/source/core/unocore/unoobj.cxx
index 8fd8e38..f7762ab 100644
--- a/sw/source/core/unocore/unoobj.cxx
+++ b/sw/source/core/unocore/unoobj.cxx
@@ -535,6 +535,11 @@ throw (lang::IllegalArgumentException)
                 sal_Int16 nLevel = 0;
                 if (rValue >>= nLevel)
                 {
+                    if (nLevel < 0 || MAXLEVEL <= nLevel)
+                    {
+                        throw lang::IllegalArgumentException(
+                            "invalid NumberingLevel", 0, 0);
+                    }
                     pTxtNd->SetAttrListLevel(nLevel);
                 }
             }
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 9e2fdff..6892f82 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1540,7 +1540,12 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext, SprmType
     case NS_sprm::LN_PBrcp:
         break;  // sprmPBrcp
     case NS_sprm::LN_PIlvl: // sprmPIlvl
-        //todo: Numbering level will be implemented in the near future (OOo 3.0?)
+            if (nIntValue < 0 || 10 <= nIntValue) // Writer can't do everything
+            {
+                SAL_INFO("writerfilter",
+                        "unsupported numbering level " << nIntValue);
+                break;
+            }
             if( m_pImpl->IsStyleSheetImport() )
             {
                 //style sheets cannot have a numbering rule attached


More information about the Libreoffice-commits mailing list