]> git.lyx.org Git - features.git/commitdiff
Fix crash reported by Tommaso:
authorRichard Heck <rgheck@lyx.org>
Mon, 4 Jun 2012 17:39:24 +0000 (13:39 -0400)
committerRichard Heck <rgheck@lyx.org>
Mon, 4 Jun 2012 17:39:24 +0000 (13:39 -0400)
  http://marc.info/?l=lyx-devel&m=133876924408431&w=2
The problem here is that the copy_params() routine in FindAndReplace.cpp
created a new DocumentClass, but it never updated its Buffer to reflect
that new DocumentClass. So its Paragraphs still contained points to the
Layouts in the old DocumentClass which, since ead697d4b6c7, gets garbage
collected once it is no longer needed. So the Layout doesn't exist, and
we crash.

src/BufferParams.h
src/BufferView.cpp
src/BufferView.h
src/frontends/qt4/FindAndReplace.cpp

index f4f9bef8e0ea068db854a26bda9eaa950b99df1f..dac9a4aef6c4c9d913710cce9aa2b81ec5a7a290 100644 (file)
@@ -124,6 +124,10 @@ public:
        bool setBaseClass(std::string const & classname);
        /// Adds the module information to the baseClass information to
        /// create our local DocumentClass.
+       /// NOTE: This should NEVER be called externally unless one immediately goes
+       /// on to class BufferView::updateDocumentClass(). The exception, of course,
+       /// is in GuiDocument, where we use a BufferParams simply to hold a copy of
+       /// the parameters from the active Buffer.
        void makeDocumentClass();
        /// Returns the DocumentClass currently in use: the BaseClass as modified
        /// by modules.
index 6c9aa366b8730b2a0bfd80a69952ff7b5f1ad1f4..ff8482d81a42ea33fda8761082198df940fa65df 100644 (file)
@@ -941,6 +941,14 @@ bool BufferView::scrollToCursor(DocIterator const & dit, bool recenter)
 }
 
 
+void BufferView::makeDocumentClass()
+{
+       DocumentClassConstPtr olddc = buffer_.params().documentClassPtr();
+       buffer_.params().makeDocumentClass();
+       updateDocumentClass(olddc);
+}
+
+
 void BufferView::updateDocumentClass(DocumentClassConstPtr olddc)
 {
        message(_("Converting document to new document class..."));
@@ -956,6 +964,7 @@ void BufferView::updateDocumentClass(DocumentClassConstPtr olddc)
        buffer_.errors("Class Switch");
 }
 
+
 /** Return the change status at cursor position, taking in account the
  * status at each level of the document iterator (a table in a deleted
  * footnote is deleted).
@@ -1256,11 +1265,9 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
        }
                
        case LFUN_LAYOUT_MODULES_CLEAR: {
-               DocumentClassConstPtr oldClass = buffer_.params().documentClassPtr();
                cur.recordUndoFullDocument();
                buffer_.params().clearLayoutModules();
-               buffer_.params().makeDocumentClass();
-               updateDocumentClass(oldClass);
+               makeDocumentClass();
                dr.screenUpdate(Update::Force);
                dr.forceBufferUpdate();
                break;
@@ -1274,11 +1281,9 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
                                "conflicts with installed modules.");
                        break;
                }
-               DocumentClassConstPtr oldClass = params.documentClassPtr();
                cur.recordUndoFullDocument();
                buffer_.params().addLayoutModule(argument);
-               buffer_.params().makeDocumentClass();
-               updateDocumentClass(oldClass);
+               makeDocumentClass();
                dr.screenUpdate(Update::Force);
                dr.forceBufferUpdate();
                break;
@@ -1305,11 +1310,9 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
                        break;
 
                // Save the old, possibly modular, layout for use in conversion.
-               DocumentClassConstPtr oldDocClass = buffer_.params().documentClassPtr();
                cur.recordUndoFullDocument();
                buffer_.params().setBaseClass(argument);
-               buffer_.params().makeDocumentClass();
-               updateDocumentClass(oldDocClass);
+               makeDocumentClass();
                dr.screenUpdate(Update::Force);
                dr.forceBufferUpdate();
                break;
@@ -1330,12 +1333,10 @@ void BufferView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
        }
 
        case LFUN_LAYOUT_RELOAD: {
-               DocumentClassConstPtr oldClass = buffer_.params().documentClassPtr();
                LayoutFileIndex bc = buffer_.params().baseClassID();
                LayoutFileList::get().reset(bc);
                buffer_.params().setBaseClass(bc);
-               buffer_.params().makeDocumentClass();
-               updateDocumentClass(oldClass);
+               makeDocumentClass();
                dr.screenUpdate(Update::Force);
                dr.forceBufferUpdate();
                break;
index d164438ad57f6a5946c2b101ccfa4c4b030b35f6..a58d25172711e33e2101e6422eaf513222a70fdb 100644 (file)
@@ -318,6 +318,8 @@ public:
        void clearLastInset(Inset * inset) const;
        /// Is the mouse hovering a clickable inset or element?
        bool clickableInset() const;
+       ///
+       void makeDocumentClass();
 
 private:
        /// noncopyable
index a4e973ba79781ea42a3d5a8c96cd14874156bbd8..610168fe5fa84962183448b80f7208f36db5af80 100644 (file)
@@ -503,7 +503,7 @@ static void copy_params(BufferView const & bv, BufferView & dest_bv) {
        Buffer & dest_buf = dest_bv.buffer();
        dest_buf.params().setLanguage(lang);
        dest_buf.params().setBaseClass(doc_class);
-       dest_buf.params().makeDocumentClass();
+       dest_bv.makeDocumentClass();
        dest_bv.cursor().current_font.setLanguage(doc_bp.language);
 }