From: Jean-Marc Lasgouttes Date: Thu, 15 Jun 2017 09:37:40 +0000 (+0200) Subject: Avoid memory reuse problems with inset-dissolve X-Git-Tag: 2.3.0beta1~243 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=9c92494e1a486;p=features.git 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. --- 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)