From ae4bca24f4cb875283e33b05f87e5dfa54fc70db Mon Sep 17 00:00:00 2001 From: attila Date: Tue, 18 Mar 2025 13:07:07 +0100 Subject: [PATCH] TextEditor: Fix crash when the caret is beyond a newline in the last position --- .../widgets/juce_TextEditor.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/modules/juce_gui_basics/widgets/juce_TextEditor.cpp b/modules/juce_gui_basics/widgets/juce_TextEditor.cpp index 92c7b0ce65..c390f9c6d5 100644 --- a/modules/juce_gui_basics/widgets/juce_TextEditor.cpp +++ b/modules/juce_gui_basics/widgets/juce_TextEditor.cpp @@ -2156,6 +2156,14 @@ std::pair, float> TextEditor::getCursorEdge (const CaretState& temp if (textStorage->isEmpty()) return { { getJustificationOffsetX(), 0.0f }, currentFont.getHeight() }; + if (visualIndex == getTotalNumChars()) + { + const auto& lastParagraph = textStorage->back().value; + + return { { getJustificationOffsetX(), lastParagraph->getTop() + lastParagraph->getHeight() }, + currentFont.getHeight() }; + } + return getTextSelectionEdge (visualIndex, tempCaret.getEdge()); } @@ -2280,17 +2288,19 @@ TextEditor::CaretState TextEditor::CaretState::withPreferredEdge (Edge newEdge) void TextEditor::CaretState::updateEdge() { - jassert (0 <= position && position <= owner.getTotalNumChars()); + // The position can be temporarily outside the current text's bounds. It's the TextEditor's + // responsibility to update the caret position after editing operations. + const auto clampedPosition = std::clamp (position, 0, owner.getTotalNumChars()); - if (position == 0) + if (clampedPosition == 0) { edge = Edge::leading; } - else if (owner.getText()[position - 1] == '\n') + else if (owner.getText()[clampedPosition - 1] == '\n') { edge = Edge::leading; } - else if (position == owner.getTotalNumChars()) + else if (clampedPosition == owner.getTotalNumChars()) { edge = Edge::trailing; }