]> git.lyx.org Git - lyx.git/commitdiff
Avoid crash when inserting macro template in tabular inset
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Tue, 27 Feb 2024 17:09:42 +0000 (18:09 +0100)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Tue, 27 Feb 2024 17:21:57 +0000 (18:21 +0100)
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
src/Text.h

index 8c8c0bf40ad0480d542962900303e25b23a6c849..9fb59b5ec9a0758ae7243fa8b7360c56ee0964c2 100644 (file)
@@ -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();
index 45fb69c5be517ca2bcbe3d85353add72ad96370c..8dc066a1613cf5c5b2bd539fc5a98a978109cdbc 100644 (file)
@@ -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.