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.
This commit is contained in:
Jean-Marc Lasgouttes 2024-02-27 18:09:42 +01:00
parent 8742f77f3a
commit 97cf2b6aef
2 changed files with 19 additions and 15 deletions

View 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. // just insert the inset and not move the cursor.
void Text::insertInset(Cursor & cur, Inset * inset) bool Text::insertInset(Cursor & cur, Inset * inset)
{ {
LBUFERR(this == cur.text()); LBUFERR(this == cur.text());
LBUFERR(inset); 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(cur.buffer()->params().track_changes
? Change::INSERTED : Change::UNCHANGED)); ? Change::INSERTED : Change::UNCHANGED));
} }
@ -5792,14 +5792,14 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
InsetMathMacroTemplate * inset = new InsetMathMacroTemplate(cur.buffer(), InsetMathMacroTemplate * inset = new InsetMathMacroTemplate(cur.buffer(),
from_utf8(token(s, ' ', 0)), nargs, false, type); from_utf8(token(s, ' ', 0)), nargs, false, type);
inset->setBuffer(bv->buffer()); inset->setBuffer(bv->buffer());
insertInset(cur, inset); if (insertInset(cur, inset)) {
// If insertion is successful, enter macro inset and select the name
// enter macro inset and select the name cur.push(*inset);
cur.push(*inset); cur.top().pos() = cur.top().lastpos();
cur.top().pos() = cur.top().lastpos(); cur.resetAnchor();
cur.resetAnchor(); cur.selection(true);
cur.selection(true); cur.top().pos() = 0;
cur.top().pos() = 0; }
} }
break; break;
@ -6734,12 +6734,15 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
case LFUN_MATH_BIGDELIM: case LFUN_MATH_BIGDELIM:
case LFUN_MATH_DISPLAY: case LFUN_MATH_DISPLAY:
case LFUN_MATH_MODE: case LFUN_MATH_MODE:
case LFUN_MATH_MACRO:
case LFUN_MATH_SUBSCRIPT: case LFUN_MATH_SUBSCRIPT:
case LFUN_MATH_SUPERSCRIPT: case LFUN_MATH_SUPERSCRIPT:
code = MATH_HULL_CODE; code = MATH_HULL_CODE;
break; break;
case LFUN_MATH_MACRO:
code = MATHMACRO_CODE;
break;
case LFUN_REGEXP_MODE: case LFUN_REGEXP_MODE:
code = MATH_HULL_CODE; code = MATH_HULL_CODE;
enable = cur.buffer()->isInternal() && !cur.inRegexped(); enable = cur.buffer()->isInternal() && !cur.inRegexped();

View File

@ -141,12 +141,13 @@ public:
void forOutliner(docstring & os, size_t maxlen, pit_type start, pit_type end, void forOutliner(docstring & os, size_t maxlen, pit_type start, pit_type end,
bool shorten = true) const; 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. /// FIXME: replace Cursor with DocIterator.
void insertChar(Cursor & cur, char_type c); 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. /// FIXME: replace Cursor with DocIterator.
void insertInset(Cursor & cur, Inset * inset); bool insertInset(Cursor & cur, Inset * inset);
/// try to handle that request /// try to handle that request
/// FIXME: replace Cursor with DocIterator. /// FIXME: replace Cursor with DocIterator.