From 9c92494e1a486435984130fc4c8274d26682ad37 Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Thu, 15 Jun 2017 11:37:40 +0200 Subject: [PATCH] Avoid memory reuse problems with inset-dissolve If 1. the inset is deleted before pasting its contents in the outer text, and 2. the inset contents begins with an inset, and 3. the clone of this inner inset is allocated at the memory location just made free, then bad things can happen. To avoid this, we delete the inset only after its contents has been pasted. Fixes bug #10667. --- src/Text.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Text.cpp b/src/Text.cpp index 038553ba44..308348595d 100644 --- a/src/Text.cpp +++ b/src/Text.cpp @@ -1745,20 +1745,24 @@ bool Text::dissolveInset(Cursor & cur) cur.recordUndoInset(); cur.setMark(false); cur.selHandle(false); - // save position + // save position inside inset pos_type spos = cur.pos(); pit_type spit = cur.pit(); ParagraphList plist; if (cur.lastpit() != 0 || cur.lastpos() != 0) plist = paragraphs(); cur.popBackward(); - // store cursor offset + // update cursor offset if (spit == 0) spos += cur.pos(); spit += cur.pit(); - Buffer & b = *cur.buffer(); - cur.paragraph().eraseChar(cur.pos(), b.params().track_changes); + // remember position outside inset to delete inset later + // we do not do it now to avoid memory reuse issues (see #10667). + DocIterator inset_it = cur; + // jump over inset + ++cur.pos(); + Buffer & b = *cur.buffer(); if (!plist.empty()) { // see bug 7319 // we clear the cache so that we won't get conflicts with labels @@ -1784,6 +1788,9 @@ bool Text::dissolveInset(Cursor & cur) cur.pos() = min(cur.lastpos(), spos); } + // delete the inset now + inset_it.paragraph().eraseChar(inset_it.pos(), b.params().track_changes); + cur.forceBufferUpdate(); // Ensure the current language is set correctly (bug 6292) -- 2.39.2