[LyX/master] Fix crash when modifying an InsetRef inserted by the current author.

Richard Kimberly Heck rikiheck at lyx.org
Sat Jul 29 01:45:11 UTC 2023


commit aacc5147b633b738579f283c518cceb305b73d38
Author: Richard Kimberly Heck <rikiheck at lyx.org>
Date:   Fri Jul 28 22:57:57 2023 -0400

    Fix crash when modifying an InsetRef inserted by the current author.
    
    The problem was that, in this case, we actually delete the current inset
    in changeCmdName. So when we return from that and attempt to call initView(),
    we're in a non-existent inset.
---
 src/Cursor.cpp              |    6 +++---
 src/insets/InsetCommand.cpp |   26 +++++++++++++++++++++++++-
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/src/Cursor.cpp b/src/Cursor.cpp
index 98b2b15..b20ab0f 100644
--- a/src/Cursor.cpp
+++ b/src/Cursor.cpp
@@ -789,15 +789,15 @@ void Cursor::dispatch(FuncRequest const & cmd0)
 
 	beginUndoGroup();
 
+	Inset * nextins = nextInset();
 	// Is this a function that acts on inset at point?
-	if (lyxaction.funcHasFlag(cmd.action(), LyXAction::AtPoint)
-	    && nextInset()) {
+	if (lyxaction.funcHasFlag(cmd.action(), LyXAction::AtPoint) && nextins) {
 		disp_.dispatched(true);
 		disp_.screenUpdate(Update::FitCursor | Update::Force);
 		FuncRequest tmpcmd = cmd;
 		LYXERR(Debug::ACTION, "Cursor::dispatch: (AtPoint) cmd: "
 			<< cmd0 << endl << *this);
-		nextInset()->dispatch(*this, tmpcmd);
+		nextins->dispatch(*this, tmpcmd);
 		if (disp_.dispatched()) {
 			endUndoGroup();
 			return;
diff --git a/src/insets/InsetCommand.cpp b/src/insets/InsetCommand.cpp
index 9ca958b..b16259d 100644
--- a/src/insets/InsetCommand.cpp
+++ b/src/insets/InsetCommand.cpp
@@ -20,6 +20,7 @@
 #include "Cursor.h"
 #include "FuncRequest.h"
 #include "FuncStatus.h"
+#include "InsetIterator.h"
 #include "Lexer.h"
 #include "LyX.h"
 #include "MetricsInfo.h"
@@ -191,7 +192,30 @@ void InsetCommand::changeCmdName(string const & new_name)
 
 	if (buffer().masterParams().track_changes) {
 		// With change tracking, we insert a new inset and
-		// delete the old one
+		// delete the old one.
+		// But we need to make sure that the inset isn't one
+		// that the current author inserted. Otherwise, we might
+		// delete ourselves!
+		InsetIterator it = begin(buffer().inset());
+		InsetIterator const itend = end(buffer().inset());
+		for (; it != itend; ++it) {
+			if (&*it == this)
+				break;
+		}
+		if (it == itend) {
+			LYXERR0("Unable to find inset!");
+			p_.setCmdName(new_name);
+			return;
+		}
+		Paragraph const & ourpara = it.paragraph();
+		pos_type const ourpos = it.pos();
+		Change const & change = ourpara.lookupChange(ourpos);
+		if (change.currentAuthor()) {
+			p_.setCmdName(new_name);
+			return;
+		}
+
+		// OK, so this is not an inset the current author inserted
 		InsetCommandParams p(p_.code());
 		p = p_;
 		p.setCmdName(new_name);


More information about the lyx-cvs mailing list