commit 5e8ace434374518502f61822e25df6ccf0dbb637 Author: Juergen Spitzmueller <sp...@lyx.org> Date: Tue Sep 23 14:40:08 2025 +0200
Prevent GuiInputMethod from accessing empty cursor slices (#13226) --- src/frontends/qt/GuiInputMethod.cpp | 44 ++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/frontends/qt/GuiInputMethod.cpp b/src/frontends/qt/GuiInputMethod.cpp index 9655599c7d..869f157936 100644 --- a/src/frontends/qt/GuiInputMethod.cpp +++ b/src/frontends/qt/GuiInputMethod.cpp @@ -293,8 +293,37 @@ void GuiInputMethod::processPreedit(QInputMethodEvent* ev) void GuiInputMethod::onCursorPositionChanged() { + if (d->cur_->atEnd()) { + // Slices are empty: + // Reset pos caches and quit. + d->cur_pos_ = 0; + d->anchor_pos_ = 0; + return; + } + d->cur_pos_ = d->cur_->top().pos(); - d->anchor_pos_ = d->cur_->realAnchor().pos(); + + // We are only interested in the current paragraph + // (where cur_pos_ is) with the anchor_pos_. + // Hence: + // 1.) If they are at document end, the realAnchor() + // slices are empty, so top() [= back()] would assert. + // We use the paragraph's last pos. + if (d->cur_->realAnchor().atEnd()) + d->anchor_pos_ = d->cur_->top().lastpos(); + // 2.) multipar-selection with anchor in later paragraph: + // Again, we use the current paragraph's last pos. + else if (d->cur_->top().pit() < d->cur_->realAnchor().pit()) + d->anchor_pos_ = d->cur_->top().lastpos(); + // 3.) multipar-selection with anchor in previous paragraph + // We use pos 0. + else if (d->cur_->top().pit() > d->cur_->realAnchor().pit()) + d->anchor_pos_ = 0; + // 4.) singlepar-selection with anchor in same paragraph + // Here, finally, we can use the realAnchor().pos() + else + d->anchor_pos_ = d->cur_->realAnchor().pos(); + setSurroundingText(*d->cur_); } @@ -1210,6 +1239,10 @@ ParagraphMetrics * GuiInputMethod::resetParagraphMetrics(Cursor * cur) pos_type GuiInputMethod::getCaretPos(size_type preedit_length) { + if (d->cur_->atEnd()) + // Slices are empty + return 0; + return d->cur_->top().pos() + preedit_length; } @@ -1324,8 +1357,17 @@ void GuiInputMethod::setSurroundingText(const Cursor & cur) { void GuiInputMethod::updatePosAndSurroundingText() { + if (d->cur_->atEnd()) { + // Slices are empty: + // Reset pos caches and quit. + d->cur_pos_ = 0; + d->anchor_pos_ = 0; + return; + } if (d->cur_->top().pos() == d->cur_pos_) + // Nothing to do return; + Q_EMIT cursorPositionChanged(); } -- lyx-cvs mailing list lyx-cvs@lists.lyx.org https://lists.lyx.org/mailman/listinfo/lyx-cvs