[LyX/master] Avoid crash when inserting macro template in tabular inset

Jean-Marc Lasgouttes lasgouttes at lyx.org
Tue Feb 27 17:26:38 UTC 2024


commit 97cf2b6aef1e0d7bc88e863b5d1d9e2920be0dd2
Author: Jean-Marc Lasgouttes <lasgouttes at lyx.org>
Date:   Tue Feb 27 18:09:42 2024 +0100

    Avoid crash when inserting macro template in tabular inset
    
    The issue here is that macro templates are forbidden in InsetTabular
    (why? I do not know) and Text::getStatus does not enforce that
    properly. Text::insertInset is called and does nothing (because
    insertion is forbidden) and yet the cursor is changed to point into
    this non existent inset.
    
    Solution:
    
    1/ block insertion of macro templates when not allowed
    
    2/ (additional safety) when insertion of a math macro inset failed, do
       not try to set cursor inside the non-existing inset.
    
    Additionally clarify comments.
---
 src/Text.cpp | 27 +++++++++++++++------------
 src/Text.h   |  7 ++++---
 2 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/src/Text.cpp b/src/Text.cpp
index 8c8c0bf40a..9fb59b5ec9 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -2965,12 +2965,12 @@ void Text::setParagraphs(Cursor const & cur, ParagraphParameters const & p)
 }
 
 
-// this really should just insert the inset and not move the cursor.
-void Text::insertInset(Cursor & cur, Inset * inset)
+// just insert the inset and not move the cursor.
+bool Text::insertInset(Cursor & cur, Inset * inset)
 {
 	LBUFERR(this == cur.text());
 	LBUFERR(inset);
-	cur.paragraph().insertInset(cur.pos(), inset, cur.current_font,
+	return cur.paragraph().insertInset(cur.pos(), inset, cur.current_font,
 		Change(cur.buffer()->params().track_changes
 		? Change::INSERTED : Change::UNCHANGED));
 }
@@ -5792,14 +5792,14 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
 			InsetMathMacroTemplate * inset = new InsetMathMacroTemplate(cur.buffer(),
 				from_utf8(token(s, ' ', 0)), nargs, false, type);
 			inset->setBuffer(bv->buffer());
-			insertInset(cur, inset);
-
-			// enter macro inset and select the name
-			cur.push(*inset);
-			cur.top().pos() = cur.top().lastpos();
-			cur.resetAnchor();
-			cur.selection(true);
-			cur.top().pos() = 0;
+			if (insertInset(cur, inset)) {
+				// If insertion is successful, enter macro inset and select the name
+				cur.push(*inset);
+				cur.top().pos() = cur.top().lastpos();
+				cur.resetAnchor();
+				cur.selection(true);
+				cur.top().pos() = 0;
+			}
 		}
 		break;
 
@@ -6734,12 +6734,15 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
 	case LFUN_MATH_BIGDELIM:
 	case LFUN_MATH_DISPLAY:
 	case LFUN_MATH_MODE:
-	case LFUN_MATH_MACRO:
 	case LFUN_MATH_SUBSCRIPT:
 	case LFUN_MATH_SUPERSCRIPT:
 		code = MATH_HULL_CODE;
 		break;
 
+	case LFUN_MATH_MACRO:
+		code = MATHMACRO_CODE;
+		break;
+
 	case LFUN_REGEXP_MODE:
 		code = MATH_HULL_CODE;
 		enable = cur.buffer()->isInternal() && !cur.inRegexped();
diff --git a/src/Text.h b/src/Text.h
index 45fb69c5be..8dc066a161 100644
--- a/src/Text.h
+++ b/src/Text.h
@@ -141,12 +141,13 @@ public:
 	void forOutliner(docstring & os, size_t maxlen, pit_type start, pit_type end,
 	                 bool shorten = true) const;
 
-	/// insert a character at cursor position
+	/// FIXME: investigate why those two function behave differently wrt cursor.
+	/// insert a character at cursor position and move cursor forward
 	/// FIXME: replace Cursor with DocIterator.
 	void insertChar(Cursor & cur, char_type c);
-	/// insert an inset at cursor position
+	/// insert an inset at cursor position; do not move cursor
 	/// FIXME: replace Cursor with DocIterator.
-	void insertInset(Cursor & cur, Inset * inset);
+	bool insertInset(Cursor & cur, Inset * inset);
 
 	/// try to handle that request
 	/// FIXME: replace Cursor with DocIterator.


More information about the lyx-cvs mailing list