mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-25 02:01:28 -05:00
Bugfix: vertical selection out of bounds (#1317)
* Fix crash bug and acknowledge that getting cell data can cause a crash
This commit is contained in:
committed by
Dustin L. Howett (MSFT)
parent
50dc8d48d9
commit
871718952c
@@ -20,17 +20,21 @@ std::vector<SMALL_RECT> Terminal::_GetSelectionRects() const
|
||||
}
|
||||
|
||||
// create these new anchors for comparison and rendering
|
||||
COORD selectionAnchorWithOffset;
|
||||
COORD endSelectionPositionWithOffset;
|
||||
COORD selectionAnchorWithOffset{ _selectionAnchor };
|
||||
COORD endSelectionPositionWithOffset{ _endSelectionPosition };
|
||||
|
||||
// Add anchor offset here to update properly on new buffer output
|
||||
THROW_IF_FAILED(ShortAdd(_selectionAnchor.Y, _selectionAnchor_YOffset, &selectionAnchorWithOffset.Y));
|
||||
THROW_IF_FAILED(ShortAdd(_endSelectionPosition.Y, _endSelectionPosition_YOffset, &endSelectionPositionWithOffset.Y));
|
||||
THROW_IF_FAILED(ShortAdd(selectionAnchorWithOffset.Y, _selectionAnchor_YOffset, &selectionAnchorWithOffset.Y));
|
||||
THROW_IF_FAILED(ShortAdd(endSelectionPositionWithOffset.Y, _endSelectionPosition_YOffset, &endSelectionPositionWithOffset.Y));
|
||||
|
||||
// clamp Y values to be within mutable viewport bounds
|
||||
selectionAnchorWithOffset.Y = std::clamp(selectionAnchorWithOffset.Y, static_cast<SHORT>(0), _mutableViewport.BottomInclusive());
|
||||
endSelectionPositionWithOffset.Y = std::clamp(endSelectionPositionWithOffset.Y, static_cast<SHORT>(0), _mutableViewport.BottomInclusive());
|
||||
|
||||
// clamp X values to be within buffer bounds
|
||||
const auto bufferWidth = _buffer->GetSize().RightInclusive();
|
||||
selectionAnchorWithOffset.X = std::clamp(_selectionAnchor.X, static_cast<SHORT>(0), bufferWidth);
|
||||
endSelectionPositionWithOffset.X = std::clamp(_endSelectionPosition.X, static_cast<SHORT>(0), bufferWidth);
|
||||
const auto bufferSize = _buffer->GetSize();
|
||||
selectionAnchorWithOffset.X = std::clamp(_selectionAnchor.X, bufferSize.Left(), bufferSize.RightInclusive());
|
||||
endSelectionPositionWithOffset.X = std::clamp(_endSelectionPosition.X, bufferSize.Left(), bufferSize.RightInclusive());
|
||||
|
||||
// NOTE: (0,0) is top-left so vertical comparison is inverted
|
||||
const COORD& higherCoord = (selectionAnchorWithOffset.Y <= endSelectionPositionWithOffset.Y) ?
|
||||
@@ -56,7 +60,7 @@ std::vector<SMALL_RECT> Terminal::_GetSelectionRects() const
|
||||
else
|
||||
{
|
||||
selectionRow.Left = (row == higherCoord.Y) ? higherCoord.X : 0;
|
||||
selectionRow.Right = (row == lowerCoord.Y) ? lowerCoord.X : bufferWidth;
|
||||
selectionRow.Right = (row == lowerCoord.Y) ? lowerCoord.X : bufferSize.RightInclusive();
|
||||
}
|
||||
|
||||
selectionRow.Left = _ExpandWideGlyphSelectionLeft(selectionRow.Left, row);
|
||||
@@ -73,10 +77,10 @@ std::vector<SMALL_RECT> Terminal::_GetSelectionRects() const
|
||||
// - position: the (x,y) coordinate on the visible viewport
|
||||
// Return Value:
|
||||
// - updated x position to encapsulate the wide glyph
|
||||
const SHORT Terminal::_ExpandWideGlyphSelectionLeft(const SHORT xPos, const SHORT yPos) const noexcept
|
||||
const SHORT Terminal::_ExpandWideGlyphSelectionLeft(const SHORT xPos, const SHORT yPos) const
|
||||
{
|
||||
// don't change the value if at/outside the boundary
|
||||
if (xPos <= 0 || xPos >= _buffer->GetSize().RightInclusive())
|
||||
if (xPos <= 0 || xPos > _buffer->GetSize().RightInclusive())
|
||||
{
|
||||
return xPos;
|
||||
}
|
||||
@@ -98,10 +102,10 @@ const SHORT Terminal::_ExpandWideGlyphSelectionLeft(const SHORT xPos, const SHOR
|
||||
// - position: the (x,y) coordinate on the visible viewport
|
||||
// Return Value:
|
||||
// - updated x position to encapsulate the wide glyph
|
||||
const SHORT Terminal::_ExpandWideGlyphSelectionRight(const SHORT xPos, const SHORT yPos) const noexcept
|
||||
const SHORT Terminal::_ExpandWideGlyphSelectionRight(const SHORT xPos, const SHORT yPos) const
|
||||
{
|
||||
// don't change the value if at/outside the boundary
|
||||
if (xPos <= 0 || xPos >= _buffer->GetSize().RightInclusive())
|
||||
if (xPos < 0 || xPos >= _buffer->GetSize().RightInclusive())
|
||||
{
|
||||
return xPos;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user